IO在 Haskell 中很棘手。线程、FFI、异步异常、惰性,凡是你能想到的。
然后我们就可以在底部MonadIO对单子堆栈进行分层。IO既然IO动作可以做任意的事情,那么在如此不稳定的基础上构建单子堆栈有什么价值呢?
它为何存在?IO如果您确实需要执行任意副作用,为什么不构建自定义 monad ?
如今,使用ReaderT 设计模式是一种常见的方法。
您对将其他变压器放在 IO 之上保持警惕是正确的,上面链接的博客文章解释了其中一些原因。
然而,当涉及到将“通用应用程序配置”传递给所有函数时,ReaderT 提供了一个很好的小便利。