为什么 runParsecT 需要两次初始用户状态?
Why does runParsecT requires the initial user state twice?
我定义了以下自定义解析器:
newtype St = St Int
type TxsParser = ParsecT String St (State St)
现在要能够 运行 这个解析器,我必须使用 runParserT
函数。
runParserT :: Stream s m t
=> ParsecT s u m a
-> u
-> SourceName
-> s
-> m (Either ParseError a)
我的自定义解析器实例化为:
runParserT :: ParsecT String St (State St) a
-> St
-> SourceName
-> String
-> State St (Either ParseError a)
但这意味着如果我想评估 runParserT
的结果(这是一个状态 monad),我必须提供另一个初始状态(在本例中为 St
类型)。例如:
evalState (runParserT myParser (St 0) fp input) (St 0)
虽然这行得通,但我必须重复两次状态似乎是错误的。这是否意味着混合 ParsecT
和 State
monads 不是一个好主意?
正确:混合 ParsecT
和 StateT
不是一个好主意。 ParsecT
monad 在回溯时小心地恢复其状态,这是一个封闭(或封闭)StateT
转换器不知道也不能正确处理的动作。
ParsecT 提供状态。状态提供状态。两者一起使用会给你两个独立的状态。
你必须同时初始化两者,这就是你看到它两次的原因。
如果您想要两个独立的状态源(例如一个回溯和一个不回溯),将它们一起使用没有错,但如果您只想要一个,这显然不是您要做的。
我定义了以下自定义解析器:
newtype St = St Int
type TxsParser = ParsecT String St (State St)
现在要能够 运行 这个解析器,我必须使用 runParserT
函数。
runParserT :: Stream s m t
=> ParsecT s u m a
-> u
-> SourceName
-> s
-> m (Either ParseError a)
我的自定义解析器实例化为:
runParserT :: ParsecT String St (State St) a
-> St
-> SourceName
-> String
-> State St (Either ParseError a)
但这意味着如果我想评估 runParserT
的结果(这是一个状态 monad),我必须提供另一个初始状态(在本例中为 St
类型)。例如:
evalState (runParserT myParser (St 0) fp input) (St 0)
虽然这行得通,但我必须重复两次状态似乎是错误的。这是否意味着混合 ParsecT
和 State
monads 不是一个好主意?
正确:混合 ParsecT
和 StateT
不是一个好主意。 ParsecT
monad 在回溯时小心地恢复其状态,这是一个封闭(或封闭)StateT
转换器不知道也不能正确处理的动作。
ParsecT 提供状态。状态提供状态。两者一起使用会给你两个独立的状态。
你必须同时初始化两者,这就是你看到它两次的原因。
如果您想要两个独立的状态源(例如一个回溯和一个不回溯),将它们一起使用没有错,但如果您只想要一个,这显然不是您要做的。