OCaml一人勉強会 - カリー化、クロージャ

関数型といえば略。
カリー化とは…ほげほげ。
例えば plus というニ引数を取る関数にうっかり引数を一つしか渡さなかったとします。

# let plus x y = x + y;;
val plus : int -> int -> int = <fun>
# plus 3;; (* アッー *)
- : int -> int = <fun>

やっちゃった…と思ったら何故か動いてしまいました。返り値は int を取り int を返す関数ということです。ふむ。
変数に束縛して引数を渡してみましょう。

# let plus_three = plus 3;;
val plus_three : int -> int = <fun>
# plus_three 2;;
- : int = 5
# plus_three 4;;
- : int = 7

とまあ、カリー化というのはこんな感じで、引数が足らなかった時に「残った引数を取る関数」を返すようにすることです。
このカリー化というものがあると、複数の引数を取る関数を、一つだけ引数を取る複数の関数に置き換えることが出来るとか、まあ知らなくても生きていけますがそういうことです。
よくよく見ると plus の型も「int -> int -> int = 」とかなんだかよくわからない感じになってますね。


さて次はクロージャです。
クロージャ(closure)というのは定義された時点での環境を保持している関数のことです…って意味不明ですね。具体的にはこのような関数のことです。

# let f x = fun y -> x + y;;
val f : int -> int -> int = <fun>
# let g = f 3;;
val g : int -> int = <fun>
# g 4;;
- : int = 7

見たまんまなんですが、関数 f の返す無名関数は f のスコープを抜けてからも引数 x を覚えているわけです。なかなか賢いです。
まあこういうのがあると便利かもしれませんしそうでもないかも知れません。
さてクロージャの書き方が分かったところでアキュムレータジェネレータを書き…たいのですが、まだ実は書けません。続きは次回。