27

我正在深入研究 Yesod 的单子,并且遇到了MonadBaseControl. 我看了一下hackage doc,然后迷路了。有人可以告诉我它试图解决的问题吗?

4

2 回答 2

21

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值。但是,如果你有一个 type 的函数Handle -> ErrorT MyError IO a并且想要获取 type 的值ErrorT MyError IO a怎么办?好吧,基本上,您必须进行修改withMyFile才能合并很多包装/展开。MonadBaseControl 允许您像withMyFile某些允许展开(“运行”)的 monad 转换器一样“提升”功能。因此,生成的代码如下所示:

useMyFileError :: (Handle -> ErrorT MyError IO ()) -> ErrorT MyError IO ()
useMyFileError func = control $ \run -> withMyFile $ run . func
于 2013-08-11T07:18:52.130 回答
20

它来自包monad-control,并且是一对类型类之一(另一个是MonadTransControl ),它们通过支持实现它的 monad的替代(resp. )操作来增强MonadBase(resp. MonadTrans )。这个增强版本不再在绝对基 monad(resp.immediate base monad)中采取简单的动作,而是采用一个函数,该函数在该点获取基本 monad(resp.monad 转换器)的整个状态作为其唯一参数并返回上述动作。liftBaselift

正如包文档所述,此增强功能以​​及这些类型类的其余内容允许您从绝对基 monad(即直接基 monad)中提升函数,如catch,allocaforkIO方案存在于MonadBase (resp. MonadTrans ),因为后者不允许你提升函数的参数,只是results,而monad-control采用的方法允许两者。

因此,可以与 MonadBaseControl (resp. MonadTransControl ) 一起使用的 monads (resp. monad transformers)集合是可以与MonadBase (resp. MonadTrans )一起使用的 monads 集合的严格子,但是前一组出于同样的原因,它们比后者强大得多。

于 2012-07-28T03:19:49.433 回答