例如,考虑以下代码:
type foo = Foo of int
let apply z f = f z
(* This is not allowed *)
let create_foo = Foo
(* This is allowed *)
let create_foo i = Foo i
(* This is not allowed *)
apply 1 Foo
(* This is allowed *)
apply 1 create_foo
Run Code Online (Sandbox Code Playgroud)
数据构造函数是必须完全应用的特殊功能吗?当作为功能使用,Foo
并create_foo
在他们所做的事情是相同的。禁止将其Foo
用作可以传递和部分应用的常规函数的原因是什么?
Haskell 似乎允许这种行为。
从马的嘴里,Xavier Leroy,在这个 2001 年的邮件列表消息中:
旧的 Caml V3.1 实现将构造函数视为类似于 SML 的函数。在 Caml Light 中,出于以下几个原因,我选择放弃这种等效性:
编译器的简单性。在内部,构造函数不是函数,需要特殊情况将 Succ 转换为 (fun x -> Succ x)。这并不难,但请记住,Caml Light 确实是 Caml 的精简版。
Caml Light 和OCaml 中的构造函数确实有一个arity,例如C of int * int 实际上是一个带有两个整数参数的构造函数,而不是一个带有一个参数的构造函数,它是一对。因此,将有两种方法将构造函数 C 映射到函数: fun (x,y) -> C(x,y) 或 fun xy -> C(x,y) 如果您来自SML 背景(其中构造函数有 0 或 1 个参数),但后者更适合 Caml Light / OCaml 执行模型,它有利于柯里化函数。通过不像函数那样对待构造函数,我们避免了必须选择......
代码清晰。虽然将构造函数用作函数有时很方便,但我认为它通常难以阅读。写“fun x -> Succ x”更冗长,但我认为更容易阅读。