我正在深入挖掘Yesod的monad,并遇到了MonadBaseControl
。
我看了一下hackage doc,迷路了。有人能告诉我它试图解决的问题吗?
答案 0 :(得分:20)
该文章的主旨可能如下:
想象一下,你有这段代码:
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)的完整状态的函数作为唯一参数并返回上述操作。
正如包文档所述,此增强功能以及这些类型类的其余内容允许您从catch
,alloca
和forkIO
中提升功能。绝对基数monad(resp。立即基数monad),这对MonadBase(resp。MonadTrans中存在的更简单的方案是不可能的,因为后一对不允许你解除参数一个函数,只有结果,而monad-control采用的方法允许两者。
因此,可以与MonadBaseControl(resp。MonadTransControl)一起使用的monad(resp.monad变换器)集合是可以与之一起使用的monad集合的严格子集。 MonadBase(分别为MonadTrans),但由于同样的原因,前任群体比后者强大得多。