前回までで Groovy 1.7 以前に Closure クラスに定義されていたメソッドは大体使ってみました(幾つか残ってますが)。 1.8から追加されたメソッドは『プログラミングGROOVY』で解説されてるし、ネット上でも記事を見つけられるので、今まで以上に雑な説明で Go。 今回はクロージャを関数として合成するメソッドです。
参考 URL
クロージャを関数として合成するメソッド
クロージャの合成を行うメソッドは leftShift(), rightShift() メソッドの2つがあり、どちらのクロージャが先に適用されるかが異なります。 Object を引数としてとる leftShift() メソッドは合成とは関係なく、クロージャを実行します。
class Closure<V>{ // 合成 Closure<V> leftShift(Closure other) <W> Closure<W> rightShift(Closure<W> other) // 実行 V leftShift(Object arg)
Groovy コード上では、通常これらのメソッドを直接呼び出さず、それぞれ「<<」と「>>」演算子によって実行します。 実行時にクロージャが適用される順番は
- f << g ・・・> f(g(...))
- f >> g ・・・> g(f(...))
となります。 数学の合成関数と順番があってるのは「<<」の方です。
Closure クラスは返り値の型を Generics の型パラメータとして指定できるので、合成に関するメソッドも型パラメータがきちんと定められます。
- f << g では返り値は(後で適用される) f と同じ方なので Closure<V> が返される
- f >> g では返り値は g と同じ型なので Closure<W> が返される(W は引数のクロージャの型パラメータに指定されている型)
まぁ、そんなに気にする必要は生じませんが。
サンプル・コード
では、サンプル・コード。 数学関数の合成みたいなサンプルはよく見るので、ここでは3つの要素をもつ List を使って置換を行うサンプルをやってみます:
// 要素の置換を行うクロージャ def f = { x -> x[2, 1, 0] } def g = { x -> x[1, 0, 2] } def x = ['a', 'b', 'c'] // 以下のように置換が実行される assert f(x) == ['c', 'b', 'a'] assert g(x) == ['b', 'a', 'c'] //***** 合成 def p = f << g // leftShift assert p(x) == f(g(x)) // ['b', 'c', 'a'] def q = f >> g // rightShift assert q(x) == g(f(x)) // ['c', 'a', 'b'] //***** 短く書くと・・・ assert (f << g)(x) == f(g(x)) // ['b', 'c', 'a'] assert (f >> g)(x) == g(f(x)) // ['c', 'a', 'b'] //***** leftShift(Object) は合成ではない assert (f << x) == f(x) assert (g << x) == g(x)
まぁ、こんな感じで。
- 作者: 関谷和愛,上原潤二,須江信洋,中野靖治
- 出版社/メーカー: 技術評論社
- 発売日: 2011/07/06
- メディア: 単行本(ソフトカバー)
- 購入: 6人 クリック: 392回
- この商品を含むブログ (152件) を見る