Cで拡張ライブラリ
を書こうとしたんだけど,makeでよく解らんエラー出たので後回しにして,RubyでListライブラリを書くことに.carやcdrを使ってScheme的に書けるようにするのが目標.
リスト構造って凄いね.inspectメソッドも再帰で書いちゃった.eachも適当に定義してEnumerableをincludeすると楽しい.でも,これだとmapで配列が返ってくるので,リストが返るように再定義.
irb(main):001:0> require 'list' => true irb(main):002:0> list = List.new(1, 2, 3) => (1 2 3) irb(main):003:0> list.car => 1 irb(main):004:0> list.cdr => (2 3) irb(main):005:0> list.map(&:succ) => (2 3 4)
楽しいなぁ.でも,ListがmoduleだったりList.newするとPairのインスタンスが返ってきたりして,実体はかなりきもいことになってる気がしないでもない.
話変わるけど,Symbol#to_procがクールすぎる.1.8なので自分で書き足しておいた.
ところで俺のfoldを見てくれ.こいつをどう思う?
def fold(init, *args, &block) result = fold(yield(init, *(args.map(&:car))), *(args.map(&:cdr)), &block) rescue NoMethodError init end
終端チェックが面倒なので例外拾うようにした.酷いコードのような気もするし,気持ち悪い気もするけど,自分ではこれ以上すっきり書ける方法は思い浮かばなかった.
誰かいい書き方があったら教えて下さい.
使う時はこんな感じ.引数の順序はEnumerable#injectに合わせた.
require 'List' include List foo, bar = List.new(1, 2, 3), List.new(4, 5, 6) p fold(0, foo, bar) {|r, x, y| r + x * y } # => 32