val seq = for(x <- 1 to 100; y <- 1 to 100; if y == x * x) yield (x, y)実は,map,flatMap,filterのシンタックスシュガーらしい.
どーいう風に展開されてるのか,知りたい.
http://d.hatena.ne.jp/matt-k/20080511#p2
実は、Scala勉強会当日にも同じ質問が出ました(そのときはScala Language SpecificationのPDFを手元に置いてなかったので、うろ覚えの知識でなんとか展開形を書きましたが)。
詳細については、Scala Language Specificationの6.19 For-Comprehensionsに書かれているので、それを読んでみるのが手っ取り早いと思いますが、とりあえず、上記の式について6.19 For-Comprehensionsに書かれている変換方法に従って展開してみることにします。
まず、
for(x <- 1 to 100; y <- 1 to 100; if y == x * x) yield (x, y)
の部分が、
A for-comprehension
for (p <- e; p' <- e' ...) yield e'', where ... is a (possibly empty) sequence of generators or guards, is translated to
e.flatmap { case p => for (p' < e' . . .) yield e'' }
に当てはまるので、
(1 to 100).flatMap{ case x => for(y <- 1 to 100; if y == x * x) yield (x, y) }
となります。次に、
y <- 1 to 100; if y == x * x
の部分が、
A generator p <- e followed by a guard if g is translated to a single generator p <- e.filter((x1, . . . , xn) => g ) where x1, ..., xn are the free variables of p.
に当てはまるので、
(1 to 100).flatMap{ case x => for(y <- (1 to 100).filter((y) => y == x * x)) yield (x, y) }
となります。最後に、
for(y <- (1 to 100).filter((y) => y == x * x)) yield (x, y)
の部分が
A for-comprehension for (p <- e) yield e' is translated to e.map { case p => e' }.
に当てはまるので、展開結果は
(1 to 100).flatMap{ case x => (1 to 100).filter((y) => y == x * x).map{ case y => (x, y) } }
となります。