什么是MonadBaseControl?

时间:2012-07-27 19:17:21

标签: haskell monads

我正在深入挖掘Yesod的monad,并遇到了MonadBaseControl。 我看了一下hackage doc,迷路了。有人能告诉我它试图解决的问题吗?

2 个答案:

答案 0 :(得分:20)

Michael Snoyman实际上写了一个关于monad-control的小教程:http://www.yesodweb.com/book/monad-control

该文章的主旨可能如下:

想象一下,你有这段代码:

withMyFile :: (Handle -> IO a) -> IO a
withMyFile = withFile "test.txt" WriteMode

您可以将withMyFile应用于Handle -> IO a类型的任何函数,并获得一个不错的IO a值。但是,如果您具有Handle -> ErrorT MyError IO a类型的函数并希望获得类型ErrorT MyError IO a的值,该怎么办?好吧,基本上,你必须修改withMyFile才能包含大量的包装/解包。 MonadBaseControl允许您将withMyFile之类的函数“升级”到某些允许展开(“运行”)的monad transfromers。因此,结果代码如下所示:

useMyFileError :: (Handle -> ErrorT MyError IO ()) -> ErrorT MyError IO ()
useMyFileError func = control $ \run -> withMyFile $ run . func

答案 1 :(得分:19)

它来自包monad-control,是一对类型类之一(另一个是MonadTransControl),它们增强MonadBase(分别为MonadTrans)通过为实现它的monad支持替代liftBase(resp。lift)操作。这个增强版本不再在绝对基础monad(resp。立即基础monad)中执行简单操作,而是采用在此时获取基本monad(resp.monad transformer)的完整状态的函数作为唯一参数并返回上述操作。

正如包文档所述,此增强功能以​​及这些类型类的其余内容允许您从catchallocaforkIO中提升功能。绝对基数monad(resp。立即基数monad),这对MonadBase(resp。MonadTrans中存在的更简单的方案是不可能的,因为后一对不允许你解除参数一个函数,只有结果,而monad-control采用的方法允许两者。

因此,可以与MonadBaseControl(resp。MonadTransControl)一起使用的monad(resp.monad变换器)集合是可以与之一起使用的monad集合的严格子集。 MonadBase(分别为MonadTrans),但由于同样的原因,前任群体比后者强大得多。