Hatena::Grouprubyist

Going My Ruby Way このページをアンテナに追加 RSSフィード

Ruby ロゴ (C) Ruby Association LLC

2011年07月17日(日)

Proc の関数(?)合成とか

| 15:08 |  Proc の関数(?)合成とか - Going My Ruby Way を含むブックマーク はてなブックマーク -  Proc の関数(?)合成とか - Going My Ruby Way  Proc の関数(?)合成とか - Going My Ruby Way のブックマークコメント

昨日、『プログラミング言語 Ruby』を立ち読みにいつもの本屋に行ったら、売れたらしく置いてませんでした。炎天下の中、往復1時間歩いたのに。。。

で、

立ち読みの日々の記憶が薄れないうちにメモです。関数合成(関数でいいのか?)についてです。

本では、lambdaproc を判別してとかやっていたようですが、難しいこと抜きにシンプルなサンプルです。(難しいことの記憶は帰途の炎天下でだいぶ溶けました)

----

f と g の合成を f(g(x)) とするのが *、g(f(x)) とするのが + です。

Proc も labmda も Method も無節操に合成してしまいます。

<<>> は前方の引数、後方の引数の部分適用です。

teetee コマンドのようなものです。

module Function
  def compose(other)
    proc {|*a| call other[*a] }
  end

  alias * compose

  def rcompose(other)
    proc {|*a| other[call *a] }
  end

  alias + rcompose

  def fa(*x)
    proc {|*a| call *(x + a) }
  end

  alias << fa

  def la(*x)
    proc {|*a| call *(a + x) }
  end

  alias >> la

  def tee(pr)
    proc {|*a| (call *a).tap{|res| pr[res]} }
  end
end

class Proc
  include Function
end

class Method
  include Function
end

実行例。ruby1.9.x で。

add   = -> a, b { a + b }
mul10 = proc {|a| a * 10 }
cout  = $>.method :puts

(add + mul10 + cout).(1, 2)                         # 30 と表示
(cout * mul10 * (add << 1) * mul10).(2)             # 210 と表示
(cout * mul10 * (add << 1).tee(cout) * mul10).(2)   # 21 と 210 の2行表示

Array#flatten の引数

| 10:44 |  Array#flatten の引数 - Going My Ruby Way を含むブックマーク はてなブックマーク -  Array#flatten の引数 - Going My Ruby Way  Array#flatten の引数 - Going My Ruby Way のブックマークコメント

Array#flatten に引数がありました(昔から?)

働きは想像どおりです。

>> [1,[2,[3,[4,[5]]]]].flatten
=> [1, 2, 3, 4, 5]
>> [1,[2,[3,[4,[5]]]]].flatten(1)
=> [1, 2, [3, [4, [5]]]]
>> [1,[2,[3,[4,[5]]]]].flatten(2)
=> [1, 2, 3, [4, [5]]]
>> [1,[2,[3,[4,[5]]]]].flatten(3)
=> [1, 2, 3, 4, [5]]
>> [1,[2,[3,[4,[5]]]]].flatten(4)
=> [1, 2, 3, 4, 5]
>> [1,[2,[3,[4,[5]]]]].flatten(5)
=> [1, 2, 3, 4, 5]