Dav*_*vid 47 io monads haskell monad-transformers
每个其他monad都带有变压器版本,据我所知,变压器的概念是monad的通用扩展.跟随其他变形金刚的构建方式,IOT就像是
newtype IOT m a = IOT { runIOT :: m (IO a) }
Run Code Online (Sandbox Code Playgroud)
我可以在现场组成有用的应用程序:IOT Maybe可以执行IO操作,IOT []也可以不执行任何操作,可以构建一个稍后可以执行的列表sequence.
那么为什么Haskell中没有IO变压器呢?
(注意:我在Haskell Cafe上看过这篇文章,但对它没有多大意义.另外,ST转换器的Hackage页面在其描述中提到了一个可能相关的问题,但没有提供任何细节.)
C. *_*ann 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
Run Code Online (Sandbox Code Playgroud)
现在你有m' :: IO (Maybe (IO b)),但你需要类型的东西Maybe (IO b),在这里-最重要的-之间的选择Just,并Nothing应确定m'.如何实施?
答案当然是,它不会,因为它不能.你也不能unsafePerformIO在那里证明一个隐藏在纯粹界面背后的东西,因为从根本上说,你要求一个纯粹的价值 - Maybe构造函数的选择- 依赖于某些东西的结果IO.Nnnnnope,不会发生.
在一般情况下情况更糟,因为任意(普遍量化)Monad甚至更难以解开IO.
顺便提一下,ST你提到的变压器的实现与你的建议不同IOT.它使用由编译器提供的魔法小精灵尘埃特殊基元ST作为类似Statemonad 的内部实现,并基于此定义类似变换器.在内部实现更加神奇,因此可以用类似的方式定义假设.StateTIOSTIOT
并不是说这真的改变了什么,除了可能让你更好地控制由不良副作用引起的相对排序IOT.