関数型ってこんな感じ
上のネタをさくっと実装してみました。とりあえず関数定義とcurry化だけ。
module FunctionalRuby FUNCS = {} def define(sym, &f) FUNCS[sym] = f self.class.module_eval("def #{sym}; FUNCS[:#{sym}]; end") end def curry(f, *vs) lambda {|v| f[vs + [v]] } end end
実行例そのいち。足し算する関数を定義して実行。ふつうlambda。何がふつうやねん。
include FunctionalRuby define(:add) do |a, b| a + b end p add[1, 2] # => 3
実行例そのに。map。パターンマッチがないのでぶかっこう。でも関数型ぽいでしょ?
include FunctionalRuby define(:map) do |f, xs| case xs when [] [] else x, *xs2 = *xs [f[x]] + map[f, xs2] end end p map[curry(add, 10), [1, 2, 3]] # => [11, 12, 13]
実行例そのさん。filter。filterの呼び出しのところでlambdaも使えます。
include FunctionalRuby define(:filter) do |f, xs| case xs when [] [] else x, *xs2 = *xs if f[x] [x] + filter[f, xs2] else filter[f, xs2] end end end p filter[lambda {|a| a > 0 }, [1, 0, 2, -4, 3, -5]] # => [1, 2, 3]
んー、関数定義のところのパターンマッチはやっぱり欲しいですね。できればガードも(その辺は開発合宿の楽しみにとっておきたいと思います)。
(追記そのいち) トラックバックどうもです。がーん、そんなライブラリがあったのですね。どうしようかな。んー、僕の勉強のためだしなー。
(追記そのに) prelude-0.3のソースを読みました。僕が思ってた実装とちょっと違うかも。自分で実装する価値はまだあるかも。