モナド・中級
ゲームライブラリをモナドにしようと思ったのだが、
いざ自分で書いてみようと思うとさーーーーっぱり書けない。
というか、完全に掌握できている(と思っている…)のが
IOモナドとMaybeモナドとListモナドぐらいなものなのだ。
そういうわけで、Monad Template Library と呼ばれる(?)もの
のアイデアぐらいはきちんと理解しておきたいと思う。
http://www.sampou.org/haskell/a-a-monads/html/
資料はこれの第2部。
- Identity Monad
bind演算は単に関数適用。
これはこれだけで使うものではない…
が、あえて使ってみた。
testIdentity = do n <- return 5 return (n*2) main = print $ runIdentity testIdentity
何がやりたいのかよく分からなくなってしまった。
- Maybe Monad
これはしってるからいいや…
深さ優先探索に用いると面白い。
- List Monad
非決定性の計算。
曖昧な文法のパーズに使えるとのこと。
そういえばそうか。
-- [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を渡しまくっているところが。
リストモナドを使うよりもパーザ自体を
モナドにしたほうが良いと思う。
例があんまり良くないんではないか?
他のものは次回…