Monads in Scalaを前回に引き続き翻訳。
ほんの少しだけど理解が深まってる感じ。
Scala's for comprehensions(Scalaでの内包表記)
"do-notation" is a syntax to write monad based program fragments:
「do表記法」はプログラムの断片を基礎とするモナドを記述するためのシンタックスです。
do x <- m1 y <- m2 return (x + y)
In Scala, this would look like this:
Scalaでは、これは次のようになる。
for(val x <- m1 m1.flatMap { x => m1.flatMap { x => val y <- m2) ==becomes==> m2.map { y => i.e. =!= m1.flatMap { x => yield {x + y} x+y }} unit (x+y) }}
jyukutyoコメント
なるほど。単なるforではなかったわけだ。
たとえばcallccInterpreter.scala | The Scala Programming Languageには
case App(f, t) => for (val a <- interp(f, e);
val b <- interp(t, e);
val c <- apply(a, b)) yield c
ってコードがある。
で、
case class M[A](value: A) { def bind[B](k: A => M[B]): M[B] = k(value) def map[B](f: A => B): M[B] = bind(x => unitM(f(x))) def flatMap[B](f: A => M[B]): M[B] = bind(f) }
のflatMapメソッドを削除すると、なぜか「val a <- interp(f, e)」の部分がコンパイルエラーになり、不思議だった。
要は上記の変換のとおり、for内包表記でflatMapメソッドに書き換えるけど、flatMapを実装していないからコンパイルエラーになったわけだ。
If we take flatMap to be bind there you have convenient syntax for monad thingies.
もしflatMapをそこにバインドされるようにすれば、モナドのための便利なシンタックスになるでしょう。
However that the =!= part has to hold, a consequence of the monad laws, is up to the programmer.
しかしながら=!=の部分が持っているものは、モナド則の結論であるが、プログラマ次第です。
We can use for-comprehension to help writing monadically structured programs, but they become monadically structured by the implementations of bind and unit, not by using for-comprehensions.
モナド的に構築されたプログラムを記述する手助けになるようにfor内包表記を使うことができるが、bindとunitの実装によってモナド的に構築されるようになるのであり、for内包表記を使うことによってモナド的になるのではありません。