我有一个解析器monad,如下所示:
data Parser b a = P(b -> [(a, b)])
instance Monad (Parser p) where
p >>= f = P $ \inp -> case parse p inp of
[] -> []
[(v, inp')] -> parse (f v) inp'
我还具有以下用于获取和设置解析器状态的功能/解析器:
getState :: Parser b b
getState = P(\inp -> [(inp, inp)])
setState b -> Parser b ()
setState s = P(\inp -> [(), s)]
此外,我还有一个解析器函数,可以向前看是否有更多解析空间而不消耗任何东西:
lookahead :: Parser b a -> Parser b ()
lookahead p = do
state <- getState
result <- p
setState state
return result
现在,假设我想编写一个解析器函数,如果另一个解析器失败,该函数将成功:如果有更多消耗,它应该失败,如果没有消耗,则成功。
notFollowedBy :: Parser b a -> Parser b ()
notFollowedBy p = do --statements
某些语法表明,这种用法的目的是禁止非法解析器继续运行。
这让我有些困惑:就我对Monads的(有限的)理解而言,它们为您提供了一个安全网,以防万一评估失败。是否有(好的和推荐的)方法可以使此功能相反?
答案 0 :(得分:2)
这是在解析器中实现notFollowedBy
的方式:
notFollowedBy :: Parser b a -> Parser b ()
notFollowedBy p = P (\inp -> case parse p inp of
[] -> [((), inp)]
_ -> [])
此定义依赖于能够访问Parser
(特别是P
构造函数)的内部。
或者,您可以执行以下操作:
notFollowedBy p = do
inp <- getState
case parse p inp of
[] -> return ()
_ -> fail "sub-parse succeeded"