Scalaz IdOps の |>
IdOps の |>
Scalaz では 以下のような構文を実行すると ある値を |> で右側の式に渡すようなことができます。
"hoge" |> (_.size)
何が起こっているかというと -Xprint:typer をつけてコンパイラの結果をみると 上記の式は
scalaz.this.Scalaz.ToIdOps[java.lang.String]("hoge").|>[Int](((x$1: java.lang.String) => scala.this.Predef.augmentString(x$1).size));
という式に変換されています。
String型の "hoge"が 型クラス IdOpsに暗黙的に変換されます。 このおかげで IdOps 型クラスに定義されている |> というメソッドが使用可能です。
ToIdOps
は IdOps.scala で定義されております。
trait ToIdOps {
implicit def ToIdOps[A](a: A): IdOps[A] = new IdOps[A] {
def self: A = a
}
}
|>
は IdOps で定義されています。
def |>[B](f: (A) ⇒ B): B
型Aをとって型Bにする関数を引数にとる関数です。
その結果 上の例の場合だと String "hoge" をとって Int で hoge のサイズ 4 を返すことになります。
実験
scala> def adddesu(s:String):String = {
| s + "-desu"
| }
adddesu: (s: String)String
こういう関数を定義し、これに |> つかって値を適用してみました。
scala> "hoge" |> adddesu
res0: String = hoge-desu
これは成功
scala> "hoge" |> adddesu()
<console>:15: error: not enough arguments for method adddesu: (s: String)String.
Unspecified value parameter s.
"hoge" |> adddesu()
^
これはエラーになりした。
scala> "hoge" |> adddesu(_)
<console>:15: error: missing parameter type for expanded function ( (x$1) => "hoge".$bar$greater(adddesu(x$1)))
"hoge" |> adddesu(_)
^
<console>:15: error: type mismatch;
found : String
required: java.lang.String => ?
"hoge" |> adddesu(_)
^
これもエラー これらの記述がエラーになるのは 上のコンパイラの展開結果をみると、納得できる。
scala> "hoge" |> (adddesu(_))
res3: String = hoge-desu
scala> "hoge".|> (adddesu(_))
res4: String = hoge-desu
scala> "hoge".|> [String](adddesu(_))
res5: String = hoge-desu
これらは OK