使用される機能は珍しいものではありませんが、かなり奇妙な機能の組み合わせであることは認めます。基本的なトリックは、Scala のすべてのブロックが式であり、その型がブロック内の最後の式と同じであるということです。最後の式が関数である場合、これはブロックに関数型があることを意味し、したがって "map" または "foreach" への引数として使用できます。これらの場合に何が起こるかというと、「map」または「foreach」が呼び出されると、ブロックが評価されます。ブロックは関数 (最初のケースでは i=> i*5 ) に評価され、その関数は範囲にマップされます。
このコンストラクトの考えられる用途の 1 つは、ブロックで変更可能な変数を定義し、結果の関数が呼び出されるたびに変数を変更することです。変数は一度初期化され、関数によって閉じられ、関数が呼び出されるたびに値が更新されます。
たとえば、最初の 6 つの階乗数を計算するやや驚くべき方法を次に示します。
(1 to 6) map {
var total = 1
i => {total *= i;total}
}
(ちなみに、例として階乗を使用して申し訳ありません。それはそれかフィボナッチのどちらかでした。Functional Progamming Guild のルールです。それについては問題があるでしょう。ホールで男の子と一緒に取り上げてください。)
ブロックに関数を返す必要があまりない理由は、ブロックの早い段階でヘルパー関数を定義することです。たとえば、2 番目の例が代わりに
(1 to 3) foreach {
def line = Console.readLine
i => println(line)
}
その結果、3 行がそれぞれ 1 回読み取られ、エコーされますが、この例では 1 回読み取られ、3 回エコーされます。