haskell - 我如何在 haskell 中抽象这个模式?

标签 haskell error-handling monads abstraction

场景:我有一个解释器,可以从 AST 自下而上构建值。某些节点带有权限——附加的 bool 表达式。权限失败应该传播,但是如果 AST 中上面的节点具有权限,则成功可以恢复计算并停止错误的传播。

起初我认为 Error MyError MyValue monad 就足够了:MyError 的成员之一可以是 PermError,我可以如果第二次检查成功,则使用 catchErrorPermError 中恢复。然而,当我到达处理程序时,MyValue 已经消失了。我想最终可能有一种方法让 PermError 携带 MyValue 字段,以便处理程序可以恢复它,但它可能会很丑陋,并且在每个步骤中检查异常会破坏一个概念异常发生。

我正在尝试考虑另一种抽象。基本上我必须返回一个数据类型 Either AllErrorsExceptPermError (Maybe PermError, MyValue) 或更简单的 (Maybe AllErrors, MyValue) (其他错误是不可恢复的并且非常适合错误单子(monad))好吧),我正在寻找一些可以让我免于处理元组的东西,因为操作的链接方式似乎有一个共同的模式。我的 haskell 知识仅限于此。在这种情况下,你将如何使用 haskell 来发挥你的优势?

当我写这篇文章时,我想到了一个想法(SO 是一只花哨的橡皮鸭):一个在内部处理类型 (a, b) 的 Monad(并最终在 Monadic 计算终止时返回它,必须有某种 runMyMonad),但让我尽可能直接使用类型 b。类似的东西

data T = Pass | Fail | Nothing
instance Monad (T , b) where
  return v = (Nothing, v)
  (Pass, v) >>= g = let (r', v') = g v in (if r' == Fail then Fail else Pass, v')
  (Fail, v) >>= g = let (r', v') = g v in (if r' == Pass then Pass else Fail, v')
  (Nothing, _) >>= g = error "This should not have been propagated, all chains should start with Pass or Fail"

errors 已被简化为 T,并且 instance 行可能存在语法错误,但您应该明白这一点。这有道理吗?

最佳答案

我认为您可以使用 State monad 进行权限和值计算,并将其包装在 ErrorT monad 转换器中来处理错误。下面是一个展示这个想法的例子,这里的计算是对一个列表进行求和,权限是列表中偶数的数量和错误条件 em> 是当我们在列表中看到 0 时。

import Control.Monad.Error
import Control.Monad.State

data ZeroError = ZeroError String
              deriving (Show)

instance Error ZeroError where


fun :: [Int] -> ErrorT ZeroError (State Int) Int
fun [] = return 0
fun (0:xs) = throwError $ ZeroError "Zero found"
fun (x:xs) = do
  i <- get
  put $ (if even(x) then i+1 else i)
  z <- fun xs
  return $ x+z


main = f $ runState (runErrorT $ fun [1,2,4,5,10]) 0
       where
         f (Left e,evens) = putStr $ show e
         f (Right r,evens) = putStr $ show (r,evens)

关于haskell - 我如何在 haskell 中抽象这个模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17668467/

相关文章:

haskell - 状态单子(monad)和 learnyouahaskell.com

haskell - 共享部分应用功能

haskell - 如何在 Edward Kmett 的 "Linear"库中使用可变大小向量?

haskell - 我如何解析这些操作?

haskell - 如何显式调用haskell语法的准引用器?

linux - 从 haskell 中控制 nice level

ios - 模态关闭后显示错误消息

spring-mvc - Thymeleaf错误消息优化

delphi - 如何识别哪些代码正在生成 "' ' 不是有效的浮点值”错误对话框

c++ - 是否有人使用带有 Expected<T> 的 monadic 绑定(bind)式编程