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

时间:2012-10-24 19:52:12

标签: haskell io monads monad-transformers

每个其他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在其描述中提到了一个可能相关的问题,但没有提供任何细节。 )

1 个答案:

答案 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)类型的内容,其中 - 最重要的是 - JustNothing之间的选择应由m'确定{1}}。如何实施?

答案当然是,它不会,因为它不能。你也不能证明unsafePerformIO在那里,隐藏在一个纯粹的界面背后,因为从根本上说你要求一个纯粹的价值 - Maybe构造函数的选择 - 依赖于某些东西的结果IO。 Nnnnnope,不会发生。

在一般情况下,情况更糟,因为任意(普遍量化的)Monad甚至比IO更难以解开。


顺便提一下,您提到的ST转换器的实施方式与建议的IOT不同。它使用ST的内部实现作为State - 使用编译器提供的 magic pixie dust 特殊基元的monad,并定义一个StateT - 就像变换器一样基于此。 IO在内部实施为更加神奇的ST,因此假设的IOT可以用类似的方式定义。

除了可能让你更好地控制由IOT引起的不纯副作用的相对排序之外,这并没有真正改变任何事情。