每个其他monad都带有变压器版本,据我所知,变换器的概念是monad的通用扩展。按照其他变换器的构建方式,IOT
将类似于
newtype IOT m a = IOT { runIOT :: m (IO a) }
我可以在现场编写有用的应用程序:IOT Maybe
可以执行IO操作,也可以不执行任何操作,IOT []
可以构建一个稍后可以sequence
d的列表。 / p>
那么为什么Haskell中没有IO变换器?
(注意:我见过this post on Haskell Cafe,但对它没有多大意义。另外,the Hackage page for the ST transformer在其描述中提到了一个可能相关的问题,但没有提供任何细节。 )
答案 0 :(得分:36)
考虑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)
类型的内容,其中 - 最重要的是 - Just
和Nothing
之间的选择应由m'
确定{1}}。如何实施?
答案当然是,它不会,因为它不能。你也不能证明unsafePerformIO
在那里,隐藏在一个纯粹的界面背后,因为从根本上说你要求一个纯粹的价值 - Maybe
构造函数的选择 - 依赖于某些东西的结果IO
。 Nnnnnope,不会发生。
在一般情况下,情况更糟,因为任意(普遍量化的)Monad
甚至比IO
更难以解开。
顺便提一下,您提到的ST
转换器的实施方式与建议的IOT
不同。它使用ST
的内部实现作为State
- 使用编译器提供的 magic pixie dust 特殊基元的monad,并定义一个StateT
- 就像变换器一样基于此。 IO
在内部实施为更加神奇的ST
,因此假设的IOT
可以用类似的方式定义。
除了可能让你更好地控制由IOT
引起的不纯副作用的相对排序之外,这并没有真正改变任何事情。