Attoparsec 是否支持保存和修改用户状态?
Does Attoparsec support saving and modifying user state?
我正在使用 Attoparsec,我想在整个解析任务中跟踪用户状态值。
我熟悉 Parsec 的单子函数 getState、putState 和 modifyState,但我似乎无法在 Attoparsec 中找到类似物。有没有一种简单的方法可以使用 Attoparsec 内部的东西或使用 State monad 来做到这一点?
您可以使用 StateT s Parser
,请注意解析器中的回溯也会回滚状态,因此您只会获得在成功解析的代码路径上调用的那些有状态操作。
{-# LANGUAGE OverloadedStrings #-}
import Data.Attoparsec.ByteString.Char8
import Control.Monad.State
import Control.Applicative
test :: StateT Int Parser ()
test = do
many $ choice [
(modify (+1) *> lift (string "car")),
(modify (+1) *> lift (string "cat"))]
pure ()
parseOnly (runStateT test 0) "catcatcat"
-- Right ((),3)
此外,我们可以开箱即用地使用大多数 Attoparsec
组合器,因为它们具有 Alternative
、MonadPlus
、Applicative
或 Monad
约束,并且 StateT
为这些定义了直通实例。我们可以使用 lift
作为基本的 Parser
-s。
我正在使用 Attoparsec,我想在整个解析任务中跟踪用户状态值。
我熟悉 Parsec 的单子函数 getState、putState 和 modifyState,但我似乎无法在 Attoparsec 中找到类似物。有没有一种简单的方法可以使用 Attoparsec 内部的东西或使用 State monad 来做到这一点?
您可以使用 StateT s Parser
,请注意解析器中的回溯也会回滚状态,因此您只会获得在成功解析的代码路径上调用的那些有状态操作。
{-# LANGUAGE OverloadedStrings #-}
import Data.Attoparsec.ByteString.Char8
import Control.Monad.State
import Control.Applicative
test :: StateT Int Parser ()
test = do
many $ choice [
(modify (+1) *> lift (string "car")),
(modify (+1) *> lift (string "cat"))]
pure ()
parseOnly (runStateT test 0) "catcatcat"
-- Right ((),3)
此外,我们可以开箱即用地使用大多数 Attoparsec
组合器,因为它们具有 Alternative
、MonadPlus
、Applicative
或 Monad
约束,并且 StateT
为这些定义了直通实例。我们可以使用 lift
作为基本的 Parser
-s。