首页 > 解决方案 > 在摇动中将 ErrIO 中的操作提升为 Action

问题描述

我使用了shake,但我调用的操作是在ErrIO 中而不是在IO monad 中。我怎样才能将这样的操作提升到Actionmonad 中。我可以runErr获取并Either赋值,然后调用throwIOliftIO(取决于结果)。这是推荐的方法吗?

代码可能是这样的:

runErr2action :: ErrIO a -> Action a
runErr2action op = liftIO $ do
    res <- runErr  op
    case res of
        Left msg -> throw msg
        Right a -> return a

也许相关的问题:为什么没有MonadErrorfor 的实例Action

标签: shake-build-system

解决方案


Shake 规则预计要么成功产生它所承诺的结果,要么失败。在大多数情况下,它调用的任何产生Left或失败值的东西都应该使用throw/ error(或理想情况下的变体IOwith liftIO,因此异常发生在不基于评估顺序的特定点)转换为异常。但是,在某些情况下,子操作失败可能不会使规则失败,例如:

  1. 也许您正在运行一个测试,而测试失败是一个有效且正确的输出,您可以通过记录失败以某种明确定义的方式处理它。在许多情况下,此类故障会在更高级别上被检测到。
  2. 也许你有两种方法来构建东西,而Either第一种方法失败了,所以你应该尝试第二种方法。

至于为什么没有MonadErrorfor 的实例Action,主要是因为MonadError类型类比较少,Shake 不依赖任何提供它们的库,所以会引入额外的依赖。它也不会比erroror提供任何显着的好处liftIO . throwError


推荐阅读