Megaparsecで状態を扱う
paser
で状態を管理したい場合があります。
Attoparsec
attoparsec
では、ライブラリ自体で、parser
利用者側の状態を管理する仕組みがありません(間違っているかも)。なので、下記にあるとおり、StateT
を使うことになります。
haskell - Does Attoparsec support saving and modifying user state? - Stack Overflow
これでできるのですが、コンビネータにlift
が必要になり煩雑です。stateT
の内側にParser
を置くことになるので、外側でコンビネータを使う場合、lifting
が必要になるからです。
Megaparsec
Megaparsec
には、ライブラリ内に、状態を管理する仕組みが備わっています。サンプルは下記です。
Using Megaparsec with state monad
Megaparsec
の場合は、parser
の内側にstate
を置くことになります。外側でstate
の関数を使う場合、ユーザはlift
する必要はありません。
lifting
はライブラリ側で行ってくれています。具体的には、ParsecT
がMonadState
クラスのインスタンスになっているからです。ライブラリの該当箇所は下記です。
https://hackage.haskell.org/package/megaparsec-6.5.0/docs/src/Text-Megaparsec-Internal.html#line-237
実行するときは、外側のparser
をrunParserT
で剥がしてから、runStateT
を使う順になります。