9

名前付きパラメーターの 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>
4

1 に答える 1

9

男性は、「結果の型が型変数である ListLabels.fold_left のような関数は、完全に適用されたと見なされないことに注意してください」と述べています。

これがあなたの例で何が起こるかです。少し絡みますのでご注意ください。

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

は単なる古典的な使用方法です: ListLabels.fold_left3 つの引数、つまり というラベルの付いた関数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]type の関数を返しますf:('a -> int -> 'a) -> init:'a -> 'a。この関数を foo としましょう。

addとというラベルの付いた 2 つの名前付き引数を指定しているためi、その型'aは 型の関数型であると推測されますadd:'c -> ~i:'d -> 'e

変数 addおよびiの型に基づいて、型は である'c必要がありint -> int -> int、 である'd必要がありますint

これらの値を type に置き換えると、 typeが'aであることがわかります。これを foo の型に置き換えると (コピペがあれば嬉しいです ;-)、その型は'aadd:(int -> int -> int) -> i:int -> '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)

不要な括弧を削除し、アルファ変換 (名前の変更)'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 の型です。~addただし、とというラベルの付いた 2 つの引数を foo に渡していることに注意してください~i。したがって、最後に取得する値は typeadd:(int -> int -> int) -> i:int -> 'aではなく、実際には type'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
于 2012-08-06T07:40:02.623 に答える