2012-08-05 51 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