Types 变体还是多态性变体?
我注意到,在我认识的OCaml程序员中,有些人总是使用多态变量(未声明的变量,前缀为反引号),而其他人从不使用多态变量,更喜欢在类型中声明的变量Types 变体还是多态性变体?,types,programming-languages,functional-programming,ocaml,ml,Types,Programming Languages,Functional Programming,Ocaml,Ml,我注意到,在我认识的OCaml程序员中,有些人总是使用多态变量(未声明的变量,前缀为反引号),而其他人从不使用多态变量,更喜欢在类型中声明的变量 除了性能方面的原因(多态变体目前的编译效率低于简单变体),OCaml专家开发人员如何在它们之间进行选择?我在大多数模块接口中使用多态变体的唯一原因是为了解决经典变体的命名问题 如果以下方法可行,多态性变体在大多数情况下将不再有用: type t1 = String of string | Int of int | Bool of bool | List
除了性能方面的原因(多态变体目前的编译效率低于简单变体),OCaml专家开发人员如何在它们之间进行选择?我在大多数模块接口中使用多态变体的唯一原因是为了解决经典变体的命名问题 如果以下方法可行,多态性变体在大多数情况下将不再有用: type t1 = String of string | Int of int | Bool of bool | List of t1 list type t2 = String of string | Int of int | Other let simplify x = match (x : t1) with String s -> String s | Int n -> Int n | Bool _ | List _ -> Other t1类型=字符串的字符串| Int of Int | Bool of Bool | t1列表的列表 类型t2=字符串的字符串| Int of Int |其他 让我们简化x= 将(x:t1)与 字符串s->字符串s |Int n->Int n |布尔_ |列表->其他
2014-02-21更新:上述代码现在在OCaml 4.01中有效。万岁 我的用法可分为以下5类。1.接口2。模块化3。易读性4。简短5。诡计
Xmlm
的类型。将作为变量类型也意味着您可以使用相同的XML处理思想开发模块,而无需引入对Xmlm
的依赖Uuidm
的。您不必编写Uuidm.create Uuidm.V4
,只需编写Uuidm.create`V4
,它同样清晰且不太冗长parse:string->[`Error of string | `Ok of t]
最后,根据第4条,我有时在模块的实现中使用多态变体。但是界面上没有显示它们。我不鼓励这种用法,除非您声明多态变体并关闭它们,因为它削弱了静态类型规则 多态性变体并不总是效率较低。以马丁为例:
type base = [`String of string | `Int of int]
type t1 = [base | `Bool of bool | `List of t1 list]
type t2 = [base | `Other]
let simplify (x:t1):t2 = match x with
| #base as b -> b
| `Bool _ | `List _ -> `Other
要对标准变体执行此操作,需要两种不同的类型和完整的重新编码,对于多态变体,基本情况是物理不变的。当使用开放递归进行术语重写时,此功能真正发挥了作用:
type leaf = [`String of string | `Int of int]
type 'b base = [leaf | `List of 'b list]
type t1 = [t1 base | `Bool of bool ]
type t2 = [t2 base | `Other]
let rec simplify (x:t1):t2 = match x with
| #leaf as x -> x
| `List t -> `List (List.map simplify t)
| `Bool _ -> `Other
当重写函数也考虑了开放递归时,优势就更大了
不幸的是,Ocaml的Hindley-Milner类型推断不足以在没有显式类型的情况下完成这类工作,这需要对类型进行仔细的因式分解,这反过来又使得原型类型很困难。此外,有时还需要显式强制
这种技术的最大缺点是,对于具有多个参数的术语,很快就会出现相当混乱的类型组合爆炸,最终更容易放弃静态强制,使用带有通配符和异常(即动态键入)的厨房水槽类型。我认为首选名称是“开放变体”现在,“开放变体”显然比“多态变体”更容易直观理解。我认为“开放变体”更准确地指的是像
exn
这样的类型。显而易见:普通ADT在类型方面并不完全等同于多态变体:如果你需要后者的特定属性,显然你必须使用它们(即,在数据类型中重叠枚举集,通过行多态性进行子类型划分)。真实世界的Ocaml有一个非常棒的总结。这应该在一些常见问题解答中。为了让我之后的读者了解何时使用多态变体这一主题:Martin的示例在Ocaml 4.01中终于合法了。高兴吧!