2012-08-05 74 views
9

尝试了解Ocaml的命名参数机制。我了解的基础知识,但doc显示像这样的例子: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 

究竟是当只有波浪中的应用是用来要去什么?它是否只是~x:x的简写,与定义相似?如果是这样,有人可以解释为什么这:

# ListLabels.fold_left;; 
- : f:('a -> 'b -> 'a) -> init:'a -> 'b list -> 'a = <fun> 

# let add = (+) and i = 0 
in ListLabels.fold_left ~add ~i [1;2;3];; 

产生

- : 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> 

回答

8

男人说 “提防功能,如ListLabels.fold_left,其结果类型是一个类型变量将永远不会被视为完全适用“。

以下是您的示例中会发生的情况。请注意这有点牵扯。

# ListLabels.fold_left;; 
- : f:('a -> 'b -> 'a) -> init:'a -> 'b list -> 'a = <fun> 

就是经典的使用:ListLabels.fold_left TAKS 3个参数,即功能标记f,一个初始化init和一个列表。

现在,

let add = (+) and i = 0 
in ListLabels.fold_left ~add ~i [1;2;3];; 

应用ListLabels.fold_left ~add ~i [1;2;3]被认为是不完整的(如男人说)。这意味着`ListLabels.fold_left首先收到其未声明的参数[1;2;3]并返回类型为f:('a -> int -> 'a) -> init:'a -> 'a的函数。让我们称这个函数为foo。

因为你给了两个命名参数,标记addi,类型'a被推断为一个功能型,add:'c -> ~i:'d -> 'e类型。

基于该变量addi的类型,类型'c必须int -> int -> int,和'd必须int

替换'a类型中的那些值,我们推导出类型'aadd:(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 
+0

哇 - 多么混乱!它确实是有道理的,非常感谢你! – scry 2012-08-06 07:58:50

+0

不客气,它也很好解决;-) – jrouquie 2012-08-06 14:16:36