为什么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,其中 – 最重要的是 – Just
和Nothing
之间的select应该由m'
决定。 那将如何实施?
答案当然是,它不会,因为它不能。 你也不能certificate那里的unsafePerformIO
,隐藏在一个纯粹的接口后面,因为从根本上说,你要求一个纯粹的值 – Maybe
构造函数的select – 依赖于IO
中某些东西的结果。 Nnnnnope,不会发生。
在一般情况下情况更糟,因为任意的(普遍量化的) Monad
比IO
更不可能解开。
顺便提一下,您提到的ST
变压器的实现方式与您build议的IOT
不同。 它使用ST
的内部实现作为类似State
的monad,使用编译器提供的magic magic dust特殊原语,并在此基础上定义了一个StateT
的变换器。 IO
在内部被实现为更神奇的ST
,因此假设的IOT
可以以类似的方式定义。
这并不是说真的会改变什么,除了可能让你更好地控制IOT
引起的不纯副作用的相对顺序。