ifもcaseも使わずに条件分岐
再び、λ楽しいよラムダの時間がやってまいりました。
true=λx.λy.x
false=λx.λy.yそうすると、変数bがtrueかfalseをとるとして
b(0)(1)
とすると、bがtrueのとき0、falseのとき1を返します。
λで条件分岐ができた!
というわけで、λで条件分岐ができると聞いて、早速やってみた。
できれば、別関数を呼ばずにすませたい!ということで・・・
true/falseの代わりに関数を返すようにする
数字を比較した結果に応じて、値を返す。
#!/opt/local/bin/ruby1.9 class Fixnum @@tr = ->(x){ ->(y){ x }} @@fl = ->(x){ ->(y){ y }} def compare(n, arr) arr[self <=> n] end def ==(n) compare n, [@@tr, @@fl, @@fl] end def >(n) compare n, [@@fl, @@tr, @@fl] end def >=(n) compare n, [@@tr, @@tr, @@fl] end def <(n) compare n, [@@fl, @@fl, @@tr] end def <=(n) compare n, [@@tr, @@fl, @@tr] end end puts (3 == 5).('foo').('bar') #=> bar puts (3 == 3).('foo').('bar') #=> foo puts (3 < 8).('foo').('bar') #=> foo puts (3 > 8).('foo').('bar') #=> bar
できた。けど・・・
FloatやStringとか色々なところでこれを書くのは面倒。
true/falseを書き換えてしまおう。
true/falseが関数を返すようにする
といっても、true/falseはTrueClass, FalseClassのインスタンス。
Classごと書き換えるのはちょっとなーってことで、ちょっと逃げてみた。
class Proc def [](n=nil) self.call n end end class TrueClass def [](n) ->(x){ ->(y){ x }}[n] end end class FalseClass def [](n) ->(x){ ->(y){ y }}[n] end end tr = ->{puts 'this is true.'} fl = ->{puts 'this is false.'} puts (('hoge' == 'hogo')[tr][fl]).() #=> this is false.
比較の結果返されたtrue, falseの[]メソッドを呼ぶと、それぞれを表す関数が返される。
呼び出しが()じゃなくなるのが汚いけど、()は定義できないみたい。
結論
ifもcaseも使わずに、条件分岐ができた!
もっと()だけで済ませられる方法とかないかなー。*1