【问题标题】:Using liftIO and monad transformers, why is the type of a bound variable IO List instead of List?使用 liftIO 和 monad 转换器,为什么绑定变量 IO 的类型是 List 而不是 List?
【发布时间】:2015-06-29 19:45:26
【问题描述】:

我将 EitherT 与 IO 结合使用来进行错误处理。我在 IO monad 中有一个从数据库获取数据的函数,因此它具有 IO [Value] 类型。我使用 liftIO 将这个函数提升到我的 EitherT IO monad 中,并将这个函数的结果绑定到一个变量。问题是 GHC 告诉我变量的类型为 IO [Value] 而不仅仅是 [Value]。我的代码是这样的

    getItem :: (IConnection a) => a -> ItemId -> EitherT String IO Item
    getItem conn id = do
                    result <- liftIO $ do
                                        ... database stuf

似乎我误解了 liftIO 和绑定变量的工作原理。我认为 liftIO 会接受 IO [Value] 并返回 EitherT String IO [Value],当绑定到一个变量时,它的类型是 [Value]。不过好像我错了。

【问题讨论】:

  • 好像在某个地方Maybe 挡道了。您能否检查(例如在 ghci 中)liftIO 中包含的表达式的类型是什么?也许发布整个函数,看看我们从哪里得到Just
  • 除此之外,您可能对Ganeti 项目(我所属的项目)使用的概念感兴趣:一个名为ResultT 的自定义monad 转换器,与EitherT 同构,但其liftIO implementation 捕获 IO 错误并将它们转换为 ResultT monad 的错误部分。这非常方便,因为失败的包装原语 IO 操作由 m​​onad 很好地处理。
  • GHC 给您的确切错误是什么?请发布足够多的代码(可能是用undefined 删除的无关内容的实现),以便我们重现您的错误。

标签: haskell monads monad-transformers


【解决方案1】:

我发现了我的问题。我在一个已经是 IO 值的值上调用 return,导致 IO (IO [Value])。

【讨论】:

  • 上次我写了一个返回IO (IO [Value])的函数是故意的,但我也做了不小心。
猜你喜欢
  • 2012-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-30
  • 2021-05-08
  • 2019-01-13
  • 1970-01-01
  • 2021-06-04
相关资源
最近更新 更多