6日目 

昨日は、flatMap を導入する Monad 型クラスをみた。また、モナディックなチェインが値にコンテキストを与えることも確認した。OptionList も標準ライブラリに flatMap があるから、新しいコードというよりは今まであったものに対して視点を変えて見るという感じになった。あと、モナディックな演算をチェインする方法としての for 構文も確認した。

for 構文、再び 

Haskell の do 記法と Scala の for 構文には微妙な違いがある。以下が do 表記の例:

foo = do
  x <- Just 3
  y <- Just "!"
  Just (show x ++ y)

通常は return (show x ++ y) と書くと思うけど、最後の行がモナディックな値であることを強調するために Just を書き出した。一方 Scala はこうだ:

scala> def foo = for {
         x <- 3.some
         y <- "!".some
       } yield x.shows + y

ほぼ同じに見えるけど、Scala の x.shows + y は素の String で、yield が強制的にその値をコンテキストに入れている。これは生の値があればうまくいく。だけど、モナディックな値を返す関数があった場合はどうすればいいだろう?

in3 start = do
  first <- moveKnight start
  second <- moveKnight first
  moveKnight second

これは Scala では moveKnight second の値を抽出して yield で再包装せずには書くことができない。

def in3: List[KnightPos] = for {
  first <- move
  second <- first.move
  third <- second.move
} yield third

この違いにより問題が生じることは実際には無いかもしれないけど、一応覚えておいたほうがいいと思う。