Monadic Parser中的否定前瞻

时间:2018-02-15 15:33:32

标签: parsing haskell monads state-monad

我有一个monadic解析器,我正在实现它作为练习。它的签名如下:

type Parser err src target = ExceptT err (State [src]) target

我已经实现了许多基本帮助程序,但是我遇到了一个需要负向前瞻的用例。特别是,我想我想做一些这样的签名:

notFollowedBy :: e -> Parser e s t -> Parser e s t' -> Parser e s t
notFollowedBy followedByError parser shouldFail = -- ...

我的想法是它可以在这样的上下文中使用:

foo = letter `notFollowedBy'` digit
    where notFollowedBy' = notFollowedBy FollwedByDigitError

我很难实施notFollowedBy,但出于各种原因:

  • 我需要一种运行shouldFail的方法,以便我可以反转它的ExceptT结果(即如果它抛出我想要捕获它并且什么也不做,但如果它没有抛出我需要抛出{{ 1}})
    • notFollowedByError不会在这里做(我不认为),我无法找到一种方法来使用catchErrorrunExceptT获取Either e t'
  • 在我运行shouldFail之前,我需要从shouldFail保存状态,因为在运行StateT之后我需要恢复状态(好像这个解析器没有运行)。但是我正在使用Lazy shouldFail,因此我不清楚是否需要将所有内容切换到严格的内容以便允许这种情况

我最好的刺不会编译,但它看起来像这样:

StateT

(作为实现说明,第一个参数实际上是notFollowedBy :: (t' -> e) -> Parser e s t -> Parser e s t' -> Parser e s t notFollowedBy onUnexpected parser shouldFail = do parsed <- parser state <- get -- This isn't strict result <- runExceptT shouldFail -- This doesn't typecheck case result of Left err -> put state >> return parsed Right t -> put state >> throwError $ onUnexpected t ,因为我想允许根据第二个解析器返回的信息自定义抛出的错误。但我不认为这对我的问题很重要。 )

类型检查失败的原因是它期待(t' -> e),但获得ExceptT (ExceptT e (State [s])) tParser e s t)。

在倾听文档并阅读ExceptT和StateT的一些来源之后,我最好的猜测是我需要模仿ExceptT e (State [s]) t(在catchError上匹配)然后使用{{1 }}。这是我对此的草率(也无法编译):

Either

第二次,类型检查员似乎对许多事情感到不满。特别是,liftCatch(来自notFollowedBy :: (t' -> e) -> Parser e s t -> Parser e s t' -> Parser e s t notFollowedBy onUnexpected parser shouldFail = do state <- get result <- parser catchSuccess' result shouldFail (throwError . onUnexpected) put state return result where catchSuccess' result = liftCatch (catchSuccess result) catchSuccess r (Left l) _ = Right r catchSuccess _ (Right r) h = Left (h r) )似乎不是我们想要的(因为它希望liftCatch返回State.Lazy)。

此时我只是在试图安抚编译器时随意排列。任何人都可以提供有关如何实施catchSuccess'的任何建议吗?

编辑:在咨询了我如何实施ExceptT(下面)后,似乎状态排序不是问题(尽管这对我来说是个谜)。因此,我的主要问题是创建notFollowedByoptional)的反向。

catchError

TL;博士

我正在尝试编写一个带有此签名的函数,当catchSuccessAndSuppressError没有抛出异常时(在运行option :: Parser e s t -> Parser e s t -> Parser e s t option parserA parserB = do state <- get parserA `catchError` \_ -> put state >> parserB 后运行时)抛出followedByError。返回时的状态应与shouldFail运行后的状态相同。

parser

0 个答案:

没有答案
相关问题