首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >组合ReaderT monads?

组合ReaderT monads?
EN

Stack Overflow用户
提问于 2012-10-24 11:53:32
回答 1查看 207关注 0票数 3

似乎能够组合不同的ReaderT环境会很有用。

例如,通用日志记录工具可能如下所示:

代码语言:javascript
复制
logit :: Text -> ReaderT Bool  IO ()
logit str = do debugflag <- ask
               liftIO $ if debugflag then putStrLn ("debug: " ++ str) else return ()

这看起来像是一个很好的可重用组件。那么,我该如何将此定义与另一个ReaderT环境集成,以便同时使用这两个环境呢?

例如,假设我想将它与这个ReaderT实例结合使用:

代码语言:javascript
复制
foo :: ReaderT Text IO ()
foo = ...

这样我就可以在同一个函数中同时使用foologit

EN

回答 1

Stack Overflow用户

发布于 2013-01-31 00:58:45

您可能希望将它们层叠成一个堆叠的monad,但它们不能堆叠在一起,因为它们都声明IO就是被包装的monad。幸运的是,您的代码已经足够通用,可以解除这一限制。您的函数的大多数常规类型都使用MonadIO,而不是专门使用IO。如果将类型更改为

代码语言:javascript
复制
 logit :: MonadIO m => Text -> ReaderT Bool m ()
 foo   :: MonadIO m =>         ReaderT Text m ()

然后,liftIO调用将通过整个堆栈将IO操作提升到底部的IO monad。

需要说明的是,您所编写的类型不需要使用liftIO,相同的类型只需要lift就可以满足,但是由于IO (简单地说)是MonadIO的一个实例,那么您(过度)专门化的类型也将通过检查器。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13042784

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档