for comprehension(for内包表記)
について・・・
forの中でyieldが使われるとfor構文全体がコレクション(ないしはイテレータ)として値を持ち、
個々の要素がyieldの右辺の値となる。
これを「for comprehension(for内包表記)」という。
やっと理解した><
たとえば・・・
scala> for ( i <- 1 to 9 if (i != 5) ) yield (i,i) res4: Seq.Projection[(Int, Int)] = RangeFM((1,1), (2,2), (3,3), (4,4), (6,6), (7,7), (8,8), (9,9))
といった感じで、これは。
scala> (1 to 9).filter(i => i != 5).map(i => (i,i)) res5: Seq.Projection[(Int, Int)] = RangeFM((1,1), (2,2), (3,3), (4,4), (6,6), (7,7), (8,8), (9,9))
と同じこと。
というか、内部的にこれに変換されている。
一応確認してみよう。
>scala -Xprint:namer fortest.scala [[syntax trees at end of namer]]// Scala source: (virtual file) package <empty> { final object Main extends scala.ScalaObject { def <init>() = { super.<init>(); () }; def main(argv: Array[String]): Unit = { val args = argv; 1.to(9).filter(((i) => i.$bang$eq(5))).map(((i) => scala.Tuple2(i, i))) } } }
となる。
ほかも
scala> (for (c <- 'a' to 'z') yield (c)) toList res19: List[Char] = List(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z)
などもOK。
調子に乗ってやってみた
scala> for (i <- 1 to 2 ; c <- 'a' to 'c') yield (i,c) <console>:5: error: type mismatch; found : Iterator[(Int, Char)] required: Iterable[?] for (i <- 1 to 2 ; c <- 'a' to 'c') yield (i,c) ^
は、失敗するのだけれど。
scala> for (i <- 1 to 2 ; c <- ('a' to 'c').toList) yield (i,c) res35: Seq.Projection[(Int, Char)] = RangeG((1,a), (1,b), (1,c), (2,a), (2,b), (2,c))
なら、うまくいく。