IT練習ノート

IT関連で調べたこと(実際は嵌ったこと)を書いています。

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はライブラリ側で行ってくれています。具体的には、ParsecTMonadStateクラスのインスタンスになっているからです。ライブラリの該当箇所は下記です。

https://hackage.haskell.org/package/megaparsec-6.5.0/docs/src/Text-Megaparsec-Internal.html#line-237

実行するときは、外側のparserrunParserTで剥がしてから、runStateTを使う順になります。