问题标签 [polymorphic-variants]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
209 浏览

ocaml - 结合参数多态性和多态变体(反引号类型)

假设我有一个由多个多态变体(协变)组成的类型,例如:

让我们进一步假设我想将此定义分解为某种类型的构造函数和一个具体的类型int。我的第一次尝试如下:

但是,使用这样的定义会产生一个非常奇怪的类型错误,其中提到了一个'b没有出现在定义中的任何地方的类型变量。

'b是一个自动生成的名称,添加显式'b将变量转换为'c.

在这种情况下,使用不变构造[ `Thing1 of type1 | `Thing2 of type 2 ]似乎可以正常工作。

但是,将类型参数显式标记为协变并不能挽救原始示例。

而且,为了更好地衡量,添加逆变注释也不起作用。

试图猜测编译器将用于未绑定类型变量的名称并将其作为参数添加到左侧也不起作用,并且会产生非常奇怪的错误消息。

有没有办法制作一个可以有效地“替换不同类型”的类型构造函数 int in [> `Ok of int | `Error of string]

0 投票
2 回答
290 浏览

functional-programming - 在 F# 中模拟多态变体?

我是 F# 的新手,所以如果这是一个愚蠢的问题或者语法可能有点不对,请提前原谅我。希望无论如何都能理解问题的要点。

我想要实现的是组合 egResult的(或Either类似的)具有不同错误类型(可区分联合)的可能性,而无需创建包含其他两个可区分联合的联合的显式可区分联合。

让我举一个例子。

假设我有一个Person这样定义的类型:

假设您有一个验证名称的函数:

另一个验证电子邮件地址:

现在我想编写validateNameand validateEmail,但问题是 中的错误类型Result有不同的类型。我想要实现的是一个函数(或运算符),它允许我做这样的事情:

|>>>是“魔术运算符”)

通过使用|>>>错误类型validatedPerson将是NameValidationError和的联合EmailValidationError

为了清楚起见,应该可以在组合链中使用任意数量的函数,即:

在像ReasonML这样的语言中,您可以使用称为多态变体的东西,但这在 F# 中不可用

是否有可能使用具有联合类型(或任何其他技术)的泛型以某种方式模仿多态变体?!或者这是不可能的?

0 投票
2 回答
62 浏览

ocaml - 多态变体和 let%bind 类型错误

对于我编写的一些代码,我正在尝试使用OCaml 中的可组合错误处理中的技术(带有错误多态变体的结果类型)。我尝试使用的函数类型如下所示:

我尝试编写它们是这样的:

不幸的是,编译器(4.09.0)报告了一个类型错误:

请注意,如果我手动执行等效操作,则代码会编译:

实际上,这并不完全正确。等效的是这个,它也无法编译(以相同的方式):

所以我的问题是这个。请注意,错误消息显示“此表达式具有类型(Nominal.term, [ `ParseError of string ]) result”。这是我不明白的——我从来没有在任何地方指定那种类型,事实上,这两个地方ParseError都提到了,它有一个>约束。那么这种类型是从哪里来的呢?IE [>ParseError of string ] become[在ParseError of string ]哪里?

还:

  • 我的尝试和 Vladimir 的原版(我假设它是编译的)有什么区别?
  • 有没有办法将多态变体从[ x ]to弱化[> x ]?(除了手动将所有标签从第一种类型映射到第二种类型)

编辑:

上传了所有的上下文代码。

编辑2(对不起):

我做了一些探索并提出了这个实现:

如果我删除任何一条注释行,则执行lex_and_parse再次开始失败。编译并且它的类型签名永远不会改变对我来说有点令人不安parse,但是调用者可能无法进行类型检查。这怎么可能?这种非局部效应严重违反了我对类型检查/签名(应该)如何工作的期望。我真的很想了解发生了什么。

0 投票
1 回答
54 浏览

ocaml - 多态变体和类型签名

(这是多态变体和 let%bind 类型错误的扩展/蒸馏)

考虑以下代码:

版本 1:

版本 2:

版本 1 类型检查,但版本 2 失败(我正在使用 4.09.0 编译):

请注意,此错误发生在 的定义中y,但两种情况下的签名x相同!怎么y能看到里面的定义x呢?是否有x比其签名更多的类型检查信息?

0 投票
1 回答
43 浏览

pattern-matching - 如何匹配包含模块之外的私有多态变体类型?

我可以使用private关键字关闭在包含模块之外创建变体类型实例的功能。

我无法创建的实例,Ordinary.t并且以下示例无法编译:

错误:无法创建私有类型 Ordinary.t 的值

但是我可以匹配Ordinary.t并且以下功能可以正常工作:

对我来说,这在逻辑上是正确的,我希望多态变体具有相同的行为。我也为这个案例创建了类比模块。

但我无法匹配Polymorphic.t。我所有的错误信息尝试如下所示:

错误:此表达式的类型为 Polymorphic.t,但表达式应为 [< `X | `是]

错误:此模式匹配 [? `X ] 但预期的模式与 Polymorphic.t 类型的值匹配

错误:语法错误

错误:此模式匹配 [? `X ] 但预期的模式与 Polymorphic.t 类型的值匹配

是否可以在声明容器之外匹配私有多态变体类型?
如果是 - 如何?如果不是 - 为什么?

0 投票
1 回答
54 浏览

c++ - caml_hash_varian 返回值在什么范围内?

20.3.6 多态变体”小节描述了如何在 C 中识别多态变体值(*它包含一个错误:应该是caml_hash_variant而不是hash_variant

我想直接将这些哈希值用作 C++ 中的错误代码。类似的东西

存档.mli:

存档.ml

存档.cpp:

返回错误代码并进行比较没有问题

但我不知道我可以返回什么状态0? -1?
是否存在无法返回的保证值caml_hash_variant

0 投票
1 回答
89 浏览

purescript - 在 purescript 中组合不同类型的变体列表

我一直在使用 Purescript 作为试验用具有行和列多态性的类似 Haskell 的语言进行编程的一种方法。

特别是,使用 Purescript 的变体包,我试图编写一个操作来按顺序组合两个“注释”列表列表,其中两个列表可能具有不相交的变体集。这里的想法是允许用户能够将在某些音符子集上声明的乐谱与包含超集的乐谱自动结合,而无需进行任何显式转换。

例如,给定以下样板文件可以更轻松地使用变体:

我可以定义以下类型:

鉴于这些,我可以定义两个分数:

所以,为了结合它们,我想要一个签名功能

但是,我对此的尝试:

产量

如果我尝试将Union v w u约束更改为约束,则错误会在第一个和第二个Union w v u之间来回出现,但我所做的任何事情似乎都无法解决这两个约束,即使我同时拥有 a和 a约束,我认为这是多余的。map expandmap expandUnion v w uUnion w v u

有什么我想念的吗?是否可以使用变体库在 Purescript 中做这样的事情?

0 投票
1 回答
243 浏览

ocaml - 多态变体-> GADT?

我正在编写一个 Prolog 系统,并且我正在使用多态变体来表示 Prolog 术语。

特别是,我使用多态变体(而不是常规变体),因此我可以进行子类型化,同时确保 OCaml 对子类型匹配的出色详尽性检查。

到目前为止,一切都很好!

在多个场合,我一直在阅读有关 GADT 的信息(在讨论.ocaml.org 和 realworldocaml.org 上)。对我来说,GADT 似乎提供了类似的功能,但内存占用更小:具有多个参数的案例的多态变体需要一个常规变体不需要的额外指针。

到目前为止,我还没有成功使用 GADT,所以这是我的问题:

是否有一种简单、直接的方法可以将使用多态变体的代码转换为 GADT?在一般情况下这甚至可能吗?

先感谢您!