什么是行类型?它们是代数数据类型吗?

时间:2018-01-04 09:56:31

标签: .net f# functional-programming ocaml

我经常听说F#缺乏对OCaml行类型的支持,这使得语言比F#更强大。

他们是什么?它们是代数数据类型,例如总和类型(有区别的联合)还是产品类型(元组,记录)?是否可以在其他方言中写行类型,例如F#?

2 个答案:

答案 0 :(得分:10)

行类型很奇怪。非常强大。

行类型用于在OCaml中实现对象和多态变体。

但首先,如果没有行类型,我们不能

type t1 = { a : int; b : string; }
type t2 = { a : int; c : bool; }

let print_a x = print_int x.a

let ab = { a = 42; b = "foo"; }
let ac = { a = 123; c = false; }

let () =
 print_a ab;
 print_a ac

此代码当然会拒绝编译,因为print_a必须具有唯一类型:t1t2,但不能同时使用两者。但是,在某些情况下,我们可能需要这种确切的行为。这就是行类型的用途。这就是他们所做的:一种更“灵活”的类型。

在OCaml中,行类型主要有两种用途:objectspolymorphic variants。在代数方面,对象为您提供“行产品”和多态变体“行和”。

关于行类型的注意事项是,你最终可以使用一些子类型进行声明,并且非常直观的类型和语义(特别是在案例类中)。

您可以查看this paper了解详情。

答案 1 :(得分:7)

我用他的例子完成PatJ's excellent answer,用类写。

鉴于以下课程:

class t1 = object
  method a = 42
  method b = "Hello world"
end

class t2 = object
  method a = 1337
  method b = false
end

以下对象:

let o1 = new t1
let o2 = new t2

您可以写下以下内容:

let print_a t = print_int t#a;;
val print_a : < a : int; .. > -> unit = <fun>

print_a o1;;

42
- : unit = ()

print_a o2;;

1337
- : unit = ()

您可以在print_a签名中看到行类型。 < a : int; .. >字面意思是&#34;任何至少包含带有签名a&#34; 的方法int的对象。