hottyです。
今回はクロージャのカリー化のお話です。

クロージャとはなにか?

クロージャについては今更説明することもあまりありませんが一応。
クロージャとは静的なスコープを持った関数であり Rubyだと手続きオブジェクトと呼ばれるものです。

ブロックをオブジェクト化したものとイメージすると良いかもしれません。
実際ブロックとクロージャは密接な関係にあります。
クロージャをブロックとして評価したり ブロック引数でブロックをクロージャとして受け取る事が可能です。

Rubyでクロージャを定義するにはlambda、proc、Proc.newなどの方法があります。
lambdaで作るクロージャはジャンプ構文や引数の取り扱いがproc、Proc.newとは異なるので注意が必要です。

さてクロージャの話はそこそこに今回の本題「カリー化について」です。

カリー化とはなにか?

Wikiでカリー化は

複数の引数をとる関数を、引数が「もとの関数の最初の引数」で戻り値が「もとの関数の残りの引数を取り結果を返す関数」であるような関数にすること。

と定義されています。

んー、文章だけではちょっと何言ってるかわからないです…。
実際に例を見たほうがわかりやすいかもしれません。
例えば以下のような関数があります。

続きを読む

見ての通り aとbを比べて大きい方(aとbが同じだったらnil)を返す関数です。
例えばこの関数を使ってある5つの数(0,5,10,99,9999)が10より大きいか比較したいと思います。

と このように書く事ができますね。

もしこのcompareという関数がカリー化されていたらどうなるか。
次の例で実際にcompareをカリー化して書きなおしてみます。

カリー化してみる

これがカリー化です。
複数の引数(a, b)をとる関数compareを、引数が「もとの関数の最初の引数(a)」で戻り値が「もとの関数の残りの引数(b)を取り 結果を返す関数」であるような関数になっていますね!

カリー化させたcompareで5つの数(0,5,10,99,9999)が10より大きいか比較するにはこのように書きます。

カリー化する事で簡潔に見やすく書くことができます。

クロージャをカリー化してみる

さてここでクロージャが登場します。
クロージャをカリー化する方法ではもっと簡単な方法があります。
ずばり Procクラスのcurryメソッドを使う方法です。

同じように例を書いてみます。

いかがでしたでしょうか。

Rubyのクロージャにはカリー化するメソッドがついているんですねー。
「カリー化…?カレーライスになるの?」なんて寒いギャグを言っている暇があったら
カリー化したほうが良い関数をどんどんカリー化して美しいコードを書いていきましょう!

あわせて読みたい記事