Scalaで、パイプライン演算子 pipeline operator
Scalaで、F#のパイプライン演算子のようなものをつくりたい。
とりあえずIntで書いてみたけどうまくいかないな。パイプのたびに()が入れ子になるのがじゃまだ。どうすればよいのだろう。うーん。再帰的な、なにかなんだろうか。
scala> val f = (x: Int) => 2 * x f: (Int) => Int = <function1> scala> val g = (x: Int) => x + 1 g: (Int) => Int = <function1> scala> val h = (x: Int) => x * x h: (Int) => Int = <function1> scala> class IntPipe (val f: Function[Int, Int]) { | def |>: (x: Int) = f.apply(x) | } defined class IntPipe scala> implicit def IntFuncPipe(f: Function[Int, Int]) = new IntPipe(f) IntFuncPipe: (f: (Int) => Int)IntPipe scala> 1 |>: f res18: Int = 2 scala> 1 |>: f |>: g <console>:15: error: type mismatch; found : (Int) => Int required: Int 1 |>: f |>: g ^ scala> (1 |>: f) |>: g res21: Int = 3 scala> ((1 |>: f) |>: g) |>: h res22: Int = 9 scala>
以下のようになるようにしたいんだよな
scala> 1 |>: f |>: g |>: h res23: Int = 9
したはちがう。
scala> (f andThen g andThen h)(1) res23: Int = 9 scala> 1 |>: ( f andThen g andThen h) res24: Int = 9
どうしたもんだか
あらためて、、、、
scala> val f = (x: Int) => 2 * x f: (Int) => Int = <function1> scala> val g = (x: Int) => x + 1 g: (Int) => Int = <function1> scala> val h = (x: Int) => x * x h: (Int) => Int = <function1> scala> class IntPipe(x: Int) { | def |> (f: Function[Int, Int]) = f.apply(x) | } defined class IntPipe scala> implicit def intToIntPipe(x: Int) = new IntPipe(x) intToIntPipe: (x: Int)IntPipe scala> 1 |> f res0: Int = 2 scala> 1 |> f |> g res1: Int = 3 scala> 1 |> f |> g |> h res2: Int = 9
おおー、うまくいった!はじめに、:があたまをよぎって、それがあたまから離れなかったのがまずかった。
でもこれだと、いちいち、implicit defが必要で、めんどうくさくて、つかいものにならないな。
さらに、あらためて、
scala> val f = (x: Int) => 2 * x f: (Int) => Int = <function1> scala> val g = (x: Int) => x + 1 g: (Int) => Int = <function1> scala> val h = (x: Int) => x * x h: (Int) => Int = <function1> scala> class Pipe[A](x: A) { | def |> [B](f: Function[A, B]) = f.apply(x) | } defined class Pipe scala> implicit def objectToPipe[A](x: A) = new Pipe(x) objectToPipe: [A](x: A)Pipe[A] scala> 1 |> f res0: Int = 2 scala> 1 |> f |> g res1: Int = 3 scala> 1 |> f |> g |> h res2: Int = 9
これで、はじめの期待通り!