Rubyでもカリー化
関数型言語ラブな人は、Rubyでもカリー化したくなってくると思います(特にHaskellラブな人はその傾向が強いように思います)。ということで、こんなメソッドを書いてみました。
module Kernel def curry(sym, *a1) f = sym.respond_to?(:call) ? sym : method(sym) lambda do |*a2| f.call(*(a1 + a2)) end end end
使い方はこんな感じです。mapの例を見てください。あぁ何て美しいのでしょう。
def add(a, b) a + b end p curry(:add, 2)[3] # => 5 p curry(method(:add), 2)[3] # => 5 p curry(lambda {|a, b| a * b}, 2)[3] # => 6 p (1 .. 10).map(&curry(:add, 10)) # => [11, 12, 13, 14, 15, 16, 17, 18, 19, 20] # # Haskellで書くとだいたいこんな感じ。 # main = print $ map (add 10) [1 .. 10] # where # add a b = a + b
ほとんどのところはふつうのRubyでコードを書いてて、ごく一部分だけピンポイントでカリー化したい場合に使えそうです。Cohi(こひ)でも似たようなことはできるのですが、全面的にRubyぽくなくなってしまうのが難点です。
lambda万歳。lambdaラブ。
参照: http://rubyforge.org/projects/cohi/