【问题标题】:What's the alternative to exceptions in a deep Haskell recursion?深度 Haskell 递归中异常的替代方法是什么?
【发布时间】:2010-09-21 16:51:24
【问题描述】:

我正在尝试通过编写小程序来学习 Haskell……所以我目前正在为简单的表达式编写一个词法分析器/解析器。 (是的,我可以使用 Alex/Happy...但我想先学习核心语言)。

我的解析器本质上是一组构建树的递归函数。在语法错误的情况下,我通常会抛出异常(即,如果我用 C# 编写),但在 Haskell 中似乎不鼓励这样做。

那么有什么选择呢?我真的不想在解析器的每一位中测试错误状态。我想要么得到一个有效的节点树,要么得到一个带有详细信息的错误状态。

【问题讨论】:

    标签: haskell exception-handling recursion


    【解决方案1】:

    Haskell 为此提供了MaybeEither 类型。既然你想返回一个错误状态,Either 似乎就是你想要的。

    【讨论】:

      【解决方案2】:

      对于可能会失败并详细说明失败原因的计算,类型为 Either a b,例如Either ErrorDetails ParseTree,因此您的结果可能是 Right theParseTreeLeft ErrorDetails。您可以在递归函数中对这些构造函数进行模式匹配,如果有错误,则将其传递;否则你照常继续。

      【讨论】:

      • 较大的 Haskell 程序通过设置 instance Monad (Either ErrorDetails) where ... 来隐藏这些细节,因此您不必在每个函数中显式处理错误情况。
      • @TomMD:是的,但你不建议新学习者“让你自己的 monad”;)
      • 好吧,只要他知道他只是通过忽略单子和转换器来学习/使用 Haskell 的四分之一。否则他会误以为 Haskell 过于冗长。
      • 编写一个显式版本的错误线程是了解 monad 为何如此有用的最佳方法之一。
      • 顺便说一句,Control.Monad.ErrorEither String a 提供了一个monad 实例,其中fail "foo" == Left "foo"return foo == Right foo
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-23
      • 2013-11-21
      • 1970-01-01
      • 2011-05-05
      • 1970-01-01
      相关资源
      最近更新 更多