昨日は、flatMap
を導入する Monad
型クラスをみた。また、モナディックなチェインが値にコンテキストを与えることも確認した。Option
も List
も標準ライブラリに flatMap
があるから、新しいコードというよりは今まであったものに対して視点を変えて見るという感じになった。あと、モナディックな演算をチェインする方法としての 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
この違いにより問題が生じることは実際には無いかもしれないけど、一応覚えておいたほうがいいと思う。