为什么ParsecT类型有'u'参数? [英] Why does ParsecT type have 'u' argument?
问题描述
u
参数来承载某些用户状态。但是,通过在 State
monad上基于 ParsecT
monad转换器可以实现相同的功能。所以如果我的解析器不是有状态的,我不需要 u
,但必须将它设置为()
与parsec。添加非可选状态支持到 ParsecT
?因为 请考虑以下示例: 正如您所看到的,基本状态monad注册了两个ticks(来自两个可供选择的替代品), Documentation for the parsec package states that Because a parser of type Consider the following example: As you can see, the underlying state monad registered two ticks (from both alternatives that were tried),
while the user state of the Parsec monad transformer only kept the successful one. 这篇关于为什么ParsecT类型有'u'参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! Parsec s st标识符a $ c $解析器的行为不同c>当涉及到回溯时:
m
不会回溯;保留最终解析结果的所有效果。
{ - #LANGUAGE FlexibleContexts# - }
module Foo其中
导入Control.Applicative
导入Control.Monad.State
import Text.Parsec.Prim hiding((< |>),State(..))
import Text.Parsec.Error(ParseError)
tick :: MonadState Int m => ParsecT s Int m()
tick = do
lift $ modify(+1)
modifyState(+1)
tickTock :: MonadState Int m => ParsecT s Int m()
tickTock =(tick>> empty)< |>勾号
- |运行具有用户状态和基础状态monad的解析器。
-
- 例如:
- >>>运行tickTock
- (Right 1,2)
run :: ParsecT String Int(State Int)() - > (或者ParseError Int,Int)
run m = runState(runParserT(m> getState)initUserState - )initStateState
其中initUserState = 0
initStateState = 0
,而Parsec monad变换器的用户状态只保留成功的。u
argument is used to carry some user state through monadic computation. But the same functionality can be achieved by basing ParsecT
monad transformer on State
monad. So if my parser is not stateful, i don't need u
altogether, but have to set it to ()
with parsec. What's rationale for adding non-optional state support to ParsecT
?ParsecT s () (State st) a
behaves differently from a parser of type Parsec s st Identity a
when it comes to backtracking:
m
does not backtrack; all the effects that happened on the way to a final parse result are kept.{-# LANGUAGE FlexibleContexts #-}
module Foo where
import Control.Applicative
import Control.Monad.State
import Text.Parsec.Prim hiding ((<|>), State(..))
import Text.Parsec.Error (ParseError)
tick :: MonadState Int m => ParsecT s Int m ()
tick = do
lift $ modify (+1)
modifyState (+1)
tickTock :: MonadState Int m => ParsecT s Int m ()
tickTock = (tick >> empty) <|> tick
-- | run a parser that has both user state and an underlying state monad.
--
-- Example:
-- >>> run tickTock
-- (Right 1,2)
run :: ParsecT String Int (State Int) () -> (Either ParseError Int, Int)
run m = runState (runParserT (m >> getState) initUserState "-" "") initStateState
where initUserState = 0
initStateState = 0