関数型言語Ruby (3)
場当たり的にパターンマッチを実装しました。とりあえずはこんなところでいいか。もう。
map。
define(:map, [X, []]) do [] end define(:map, [X, X_XS]) do |f, x, xs| [f[x]] + map[f, xs] end
filter。
define(:filter, [X, []]) do [] end define(:filter, [X, X_XS]) do |f, x, xs| if f[x] [x] + filter[f, xs] else filter[f, xs] end end
実装。
module FunctionalRuby FUNCS = {} X = Object.new X_XS = Object.new class Function def initialize(sym) @sym = sym @func = [] end def add(pat, &f) @func.push([pat, f]) end def [](*xs) @func.each do |func| pat, f = *func xs2 = match_pattern?(pat, xs) return f[*xs2] if xs2 end raise(ArgumentError, "no match pattern. #{@sym}") unless f end private def match_pattern?(pat, xs) return xs unless pat return nil unless pat.size == xs.size xs2 = [] pat.zip(xs) do |pat, x| case pat when X xs2 << x next when X_XS y, *ys = *x xs2 << y xs2 << ys next when x next else return nil end end xs2 end end def define(sym, pat = nil, &f) FUNCS[sym] ||= Function.new(sym) FUNCS[sym].add(pat, &f) self.class.module_eval("def #{sym}; fun(:#{sym}); end") end def curry(f, *vs) lambda {|v| f[vs + [v]] } end def fun(sym) FUNCS[sym] end end