【问题标题】:Is there any difference between "MonadIO m" and "MonadBaseControl IO m"?“MonadIO m”和“MonadBaseControl IO m”有什么区别吗?
【发布时间】:2014-01-22 18:05:21
【问题描述】:

来自 network-conduit 的函数 runTCPClient 具有以下签名:

runTCPClient :: (MonadIO m, MonadBaseControl IO m)
             => ClientSettings m -> Application m -> m ()

MonadIO m 提供

liftIO :: IO a -> m a

MonadBaseControl IO m 提供

liftBase :: IO a -> m a

没有明显的区别。它们提供相同的功能吗?如果是,为什么类型签名中有重复?如果不是,有什么区别?

【问题讨论】:

    标签: haskell monads conduit


    【解决方案1】:

    liftBaseMonadBase 的一部分,它是 MonadIO 对于任何基本 monad 的泛化,正如您所说,MonadBase IO 提供与 MonadIO 相同的功能。

    不过,MonadBaseControl 有点复杂。在MonadBaseControl IO m 你有

    liftBaseWith :: ((forall a. m a -> IO (StM m a)) -> IO a) -> m a
    restoreM     :: StM m a -> m a
    

    通过查看示例最容易了解实际用途。例如,base 中的 bracket 具有签名

    bracket ::  IO a -> (a -> IO b) -> (a -> IO c) -> IO c
    

    只需MonadBase IO m(或MonadIO m),您就可以将主要的bracket 调用提升为m,但括号操作仍需要使用普通的旧IO

    throwcatch 可能是更好的例子:

    throw :: Exception e => e -> a
    catch :: Exception e => IO a -> (e -> IO a) -> IO a
    

    您可以轻松地从任何MonadIO m 抛出异常,并且可以从MonadIO m 内部的IO a 捕获异常,但同样,在catch 中运行的操作和异常处理程序本身都需要为IO a不是m a

    现在MonadBaseControl IO 使得编写bracketcatch 成为可能,从而允许参数操作也属于m a 类型,而不是仅限于基本单子。上述函数(以及许多其他函数)的通用实现可以在包lifted-base 中找到。例如:

    catch   :: (MonadBaseControl IO m, Exception e) => m a -> (e -> m a) -> m a
    bracket :: MonadBaseControl IO m => m a -> (a -> m b) -> (a -> m c) -> m c
    

    编辑:现在我实际上正确地重新阅读了您的问题......

    不,我看不出签名需要MonadIO mMonadBaseControl IO m 的任何原因,因为MonadBaseControl IO m 应该暗示MonadBase IO m 启用完全相同的功能。所以也许它只是一些旧版本的遗留物。

    查看源代码,可能只是因为runTCPClient 在内部调用了sourceSocketsinkSocket,而那些需要MonadIO。我猜包中的所有函数不简单使用MonadBase IO的原因是MonadIO对人们来说更熟悉,大多数monad转换器都有一个为MonadIO m => MonadIO (SomeT m)定义的实例,但用户可能必须编写他们自己的 MonadBase IO 实例。

    【讨论】:

    • 谢谢,现在说得通了。让我感到困惑的是 MonadBaseControl in conduit 没有任何定义,可能只有名称是在那里导入/重新导出的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-07
    • 2017-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多