Ocaml';s命名参数

Ocaml';s命名参数,ocaml,currying,named-parameters,Ocaml,Currying,Named Parameters,试图理解Ocaml命名参数的机制。我了解基本知识,但示例如下: # let f ~x ~y = x - y;; val f : x:int -> y:int -> int = <fun> # let x = 3 and y = 2 in f ~x ~y;; - : int = 1 产生 - : f:((add:(int -> int -> int) -> i:int -> 'a) -> int -> add:(int ->

试图理解Ocaml命名参数的机制。我了解基本知识,但示例如下:

# let f ~x ~y = x - y;;
val f : x:int -> y:int -> int = <fun>

# let x = 3 and y = 2 in f ~x ~y;;
- : int = 1
产生

- : f:((add:(int -> int -> int) -> i:int -> 'a) ->
   int -> add:(int -> int -> int) -> i:int -> 'a) ->
init:(add:(int -> int -> int) -> i:int -> 'a) -> 'a = <fun>
-:f:((添加:(int->int->int)->i:int->'a)->
int->add:(int->int->int)->i:int->a)->
初始:(添加:(int->int->int)->i:int->a)->a=
那人说 “请注意,结果类型为类型变量的函数(如ListLabels.fold_left)永远不会被视为完全应用。”

下面是您的示例中发生的情况。当心,有点牵扯其中

# ListLabels.fold_left;;
- : f:('a -> 'b -> 'a) -> init:'a -> 'b list -> 'a = <fun>
应用程序
ListLabels.fold\u left~add~i[1;2;3]
被认为是不完整的(正如该男子所说)。这意味着
`ListLabels.fold_left
首先接收其未指定的参数
[1;2;3]
,并返回类型为
f:('a->int->'a)->init:'a->'a
的函数。让我们把这个函数称为foo

由于您给出了两个命名参数,分别标记为
add
i
,因此类型
'a
被推断为一个函数类型,类型为
add:'c->~i:'d->'e

根据变量的类型
add
i
,类型
'c
必须是
int->int->int
,而
'd
必须是
int

替换类型
'a
中的那些值,我们得出类型
'a
add:(int->int->int)->i:int->'e
。 将其替换为foo类型(我很高兴有复制粘贴;-),其类型为

f:((add:(int -> int -> int) -> i:int -> 'e)
    -> int
    -> (add:(int -> int -> int) -> i:int -> 'e))
-> init:(add:(int -> int -> int) -> i:int -> 'e)
-> (add:(int -> int -> int) -> i:int -> 'e)
删除不必要的括号,并将
'e
转换为
'a
,我们得到

f:((add:(int -> int -> int) -> i:int -> 'a)
    -> int
    -> add:(int -> int -> int) -> i:int -> 'a)
-> init:(add:(int -> int -> int) -> i:int -> 'a)
-> add:(int -> int -> int) -> i:int -> 'a
这就是foo的类型。但请记住,您正在向foo传递两个参数,分别标记为
~add
~i
。因此,最后得到的值不是类型
add:(int->int->int)->i:int->'a
,而是类型
'a
。您的示例的整个类型是,正如编译器返回的

f:((add:(int -> int -> int) -> i:int -> 'a)
    -> int
    -> add:(int -> int -> int) -> i:int -> 'a)
-> init:(add:(int -> int -> int) -> i:int -> 'a)
-> 'a

哇-真是一团糟!不过这确实有道理,非常感谢!
f:((add:(int -> int -> int) -> i:int -> 'a)
    -> int
    -> add:(int -> int -> int) -> i:int -> 'a)
-> init:(add:(int -> int -> int) -> i:int -> 'a)
-> add:(int -> int -> int) -> i:int -> 'a
f:((add:(int -> int -> int) -> i:int -> 'a)
    -> int
    -> add:(int -> int -> int) -> i:int -> 'a)
-> init:(add:(int -> int -> int) -> i:int -> 'a)
-> 'a