为什么Haskell中没有IO变换器?

每一个monad都有一个变压器版本,从我所知道的变压器的想法是单子的通用扩展。 跟随其他变压器的build立, IOT将是类似的东西

 newtype IOT ma = IOT { runIOT :: m (IO a) } 

为此,我可以在现场IOT Maybe有用的应用程序: IOT Maybe可以执行一个IO操作,也可以不执行任何操作, IOT []可以创build一个列表,稍后可以将其作为sequence d。

那么为什么Haskell中没有IO变压器呢?

(注意:我在Haskell Cafe看过这篇文章 ,但是没有太多意义, ST转换器的Hackage页面在其描述中提到了一个可能相关的问题,但是没有提供任何细节。

考虑一下IOT Maybe的具体例子。 你会怎么写一个Monad实例呢? 你可以从这样的事情开始:

 instance Monad (IOT Maybe) where return x = IOT (Just (return x)) IOT Nothing >>= _ = IOT Nothing IOT (Just m) >>= k = IOT $ error "what now?" where m' = liftM (runIOT . k) m 

现在你有m' :: IO (Maybe (IO b)) ,但是你需要Maybe (IO b)types,其中 – 最重要的是 – JustNothing之间的select应该由m'决定。 那将如何实施?

答案当然是,它不会,因为它不能。 你也不能certificate那里的unsafePerformIO ,隐藏在一个纯粹的接口后面,因为从根本上说,你要求一个纯粹的值 – Maybe构造函数的select – 依赖于IO中某些东西的结果。 Nnnnnope,不会发生。

在一般情况下情况更糟,因为任意的(普遍量化的) MonadIO更不可能解开。


顺便提一下,您提到的ST变压器的实现方式与您build议的IOT不同。 它使用ST的内部实现作为类似State的monad,使用编译器提供的magic magic dust特殊原语,并在此基础上定义了一个StateT的变换器。 IO在内部被实现为更神奇的ST ,因此假设的IOT可以以类似的方式定义。

这并不是说真的会改变什么,除了可能让你更好地控制IOT引起的不纯副作用的相对顺序。