OCaml:为什么`let f : int -> int list -> int list = (::);;` 会失败?

Add*_*dem 1 ocaml partial-application

我认为 OCaml 会阅读

let f : int -> int list -> int list = (::);;
Run Code Online (Sandbox Code Playgroud)

作为部分应用的实例,并将函数存储为f. 但是,编译器抱怨该函数应用于太少的参数。对此的任何见解将不胜感激,谢谢。

Jef*_*eld 5

::OCaml 中的值是一个构造函数而不是一个通用函数。因此,它需要以下参数(在括号中)。您可以在(::)表单中使用它,但必须后跟括号中的两个值:

# ( :: ) (3, []);;
- : int list = [3]
Run Code Online (Sandbox Code Playgroud)

其他构造函数也是如此,例如Some

# let f : 'a -> 'a option = Some
Error: The constructor Some expects 1 argument(s),
       but is applied here to 0 argument(s)
Run Code Online (Sandbox Code Playgroud)

你当然可以这样定义你的函数:

let f : int -> int list -> int list = fun a b -> (::) (a, b)
Run Code Online (Sandbox Code Playgroud)

或这个:

let f : int -> int list -> int list = fun a b -> a :: b
Run Code Online (Sandbox Code Playgroud)

或者甚至像这样:

let f : int -> int list -> int list = List.cons
Run Code Online (Sandbox Code Playgroud)

(其他语言,尤其是 Haskell,将构造函数视为函数。因此您可以使用部分应用的构造函数等。在我看来,这在美学上更优越,即看起来更优雅。)