Parsec で do を使わない方法
do 記法は審美的に問題
Parsecでパーサを使ったパターン定義に Applicative を使ってその簡潔な記述法に慣れてしまうと、do 記法を使うのが嫌になってきた。たとえば Applicative で記述したつぎのようなパターンを、
Prelude Text.Parsec> parseTest (char '(' *> many letter <* char ')') "(hello)" "hello"
do 記法で記述すると次のようになって審美的にも好ましくない。
Prelude Text.Parsec> parseTest (do char '('; x <- many letter; char ')'; return x) "(hello)" "hello"
しかし、パターンの連接は do 記法でないと書けない。
Prelude Text.Parsec> parseTest (do string "foo"; string "bar") "foobar" "bar"
do 記法を使わない方法
しかし、幸いなことに Parsec のパーサーモナドはモナド値を次のモナドで利用することはあまりない。したがって do ... ; ... の代わりにモナド演算子の >> を使うことができる。このやり方だと上のパターンは、string "foo" >> stirng "bar" と書けて、余分な do 記法がいらない。Prelude Text.Parsec> parseTest (string "foo" >> string "bar") "foobar" "bar"
>> 演算子で連結したパーサは many などのパーサコンビネータの引数にすることもできる。
Prelude Text.Parsec> parseTest (many (string "foo" >> string "bar")) "foobarfoobar" ["bar","bar"]
しかし、次のように前後のパターンにマッチした文字列を結合して戻り値にしたいときは do 記法がいる。
Prelude Text.Parsec> parseTest (do x <- string "foo"; y <- string "bar"; return (x++y)) "foobar" "foobar"
しかし、これは Applicative を使えば次のように書ける。
Prelude Text.Parsec> parseTest ((++) <$> string "foo" <*> string "bar") "foobar" "foobar"
Applicative と >> モナド演算子のおかげで、Parsec のパターン記述に do 記法と return を極力使わないで済みそうだ。