gpt4 book ai didi

parsing - 使用 Maybe 进行错误检测和报告

转载 作者:行者123 更新时间:2023-12-04 23:03:48 24 4
gpt4 key购买 nike

我正在用 Haskell 编写一个命题逻辑解析器。作为学习练习,我现在正在手动进行解析。最终我将解决 Parsec。与此同时,我正试图将我的头围绕在 Monads 上。特别是,我使用 Maybe 来报告来自我的 parse 函数的错误。我目前的问题是辅助函数的一部分:

parse' :: String -> (Maybe Wff, String)
parse' ('[':rest) = (x, if null rest''
then ""
else tail rest'')
where (a, rest') = parse' rest
(b, rest'') = parse' (if null rest'
then ""
else tail rest')
x = if null rest'
|| null rest''
|| head rest' /= '|'
|| head rest'' /= ']'
then Nothing
else Or <$> a <*> b

(作为引用,完整的 parse 函数可以在 here 中找到。)

此代码解析 [ A | B ] 形式的命题,其中 AB 是任意命题。如您所见,如果先前的递归调用导致 Nothing ,我将在最后一行使用 applicative 样式来传播 Nothing 结果。这允许我从 a == Nothing 条件中取出 b == Nothingif。如何使用 ApplicativeMonadMaybe 实例来折叠此 if 的其余部分?

最佳答案

您可以使用 Control.Monad 中名为 guard 的函数。这有一个有点奇怪的类型:

guard :: MonadPlus m => Bool -> m ()
MonadPlus 涵盖了所有具有“空”大小写的 monad。对于列表,这是 [] ;对于 MaybeNothingguard 需要一个 bool 值;如果是 False ,则计算为该空值;否则计算结果为 return () 。这种行为在 do 表示法中最有用:
x = do guard (not $ null rest' || null rest'' || head rest' /= '|' || head rest'' /= ']')
Or <$> a <*> b

这里发生的事情很简单。如果条件评估为 True ,guard 返回 Just () ,然后忽略它以支持 Or <$> a <*> b (因为这就是 do 表示法的工作方式)。但是,如果条件是 Falseguard 返回 Nothing ,它通过 do 符号的其余部分传播,为您提供 Nothing 的最终结果:正是您想要的。

为了使代码更具可读性,我还将条件提取到 where 块中它自己的变量中。

关于parsing - 使用 Maybe 进行错误检测和报告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17056075/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com