2012-08-05 12 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はunamed引数 [1;2;3]を最初に受け取り、タイプ f:('a -> int -> 'a) -> init:'a -> 'aの関数を返します。この関数をfooと呼ぶことにしよう。

あなたはaddiラベルされた2つの名前付き引数を、与えているので、タイプ'aはタイプadd:'c -> ~i:'d -> 'eの機能タイプであると推測されます。

変数addiのタイプに基づいて、タイプ'cint -> int -> intでなければならない、と'dintでなければなりません。

タイプ'aの値を置き換えると、タイプ'aadd:(int -> int -> int) -> i:int -> 'eであることがわかります。 そしてそのタイプは'aに(つまり、名前の変更)'e変換

に、不要な括弧を削除
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) 

、およびアルファである、(私はコピー&ペーストが;-)ありうれしいFOOの種類でこれを置き換える、我々が得ます

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という2つの引数を渡していることに注意してください。したがって、最終的に得られる価値は、タイプ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

+0

あなたも大歓迎ですが、解決するのも良かったです;-) – jrouquie

関連する問題