モナド・中級

ゲームライブラリをモナドにしようと思ったのだが、
いざ自分で書いてみようと思うとさーーーーっぱり書けない。
というか、完全に掌握できている(と思っている…)のが
IOモナドとMaybeモナドとListモナドぐらいなものなのだ。
そういうわけで、Monad Template Library と呼ばれる(?)もの
のアイデアぐらいはきちんと理解しておきたいと思う。

http://www.sampou.org/haskell/a-a-monads/html/
資料はこれの第2部。

bind演算は単に関数適用。
これはこれだけで使うものではない…
が、あえて使ってみた。

testIdentity = do
  n <- return 5
  return (n*2)

main = print $ runIdentity testIdentity

何がやりたいのかよく分からなくなってしまった。

これはしってるからいいや…
深さ優先探索に用いると面白い。

非決定性の計算。
曖昧な文法のパーズに使えるとのこと。
そういえばそうか。

 -- [c] を引数に (r,[c]) を返すような非決定性な計算
type Parser c r = [c] -> [(r,[c])]

satisfy :: (a -> Bool) -> Parser a a
satisfy p (x:xs) | p x = return (x,xs)
satisfy _ _            = fail "satisfy"

success :: r -> Parser c r
success r xs = return (r,xs)

failure :: Parser c r
failure _ = fail "failure"

まぁ、こんな感じで。
コンビネータは bind と mplus で頑張る。
bind が <&> に、 mplusが <|> に対応。

many p xs = pp xs `mplus` success [] xs where
  pp xs = do
    (r, xs) <- p xs
    (rs,xs) <- many p xs
    return (r:rs,xs)

こんな感じで書ける。

main = print $ many number "123  "
=> [("123","  "),("12","3  "),("1","23  "),("","123  ")]

ちゃんと動いてはいるようだが、
さっきのmanyとかのコードはあんまり嬉しくないかも…
xsを渡しまくっているところが。


リストモナドを使うよりもパーザ自体を
モナドにしたほうが良いと思う。
例があんまり良くないんではないか?


他のものは次回…