Haskell失败使单子成功

时间:2019-03-06 20:24:54

标签: parsing haskell

我有一个解析器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的(有限的)理解而言,它们为您提供了一个安全网,以防万一评估失败。是否有(好的和推荐的)方法可以使此功能相反?

1 个答案:

答案 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"