56

每个其他 monad 都带有一个转换器版本,据我所知,转换器的概念是 monad 的通用扩展。按照其他变压器的构建方式,IOT将类似于

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

为此我可以在现场编写有用的应用程序:IOT Maybe可以执行 IO 操作或不执行任何操作,IOT []可以构建一个以后可以使用的列表sequence

那么为什么 Haskell 中没有 IO 转换器呢?

(注意:我在 Haskell Cafe 上看到过这篇文章,但无法理解。此外,ST 变压器的 Hackage 页面在其描述中提到了一个可能相关的问题,但没有提供任何细节。)

4

1 回答 1

39

考虑具体的例子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应该Nothingm'. 那将如何实施?

当然,答案是它不会,因为它不能。你也不能证明unsafePerformIO隐藏在纯接口后面的 in 是合理的,因为从根本上说,你要求一个纯值——Maybe构造函数的选择——依赖于IO. Nnnnnope,不会发生。

在一般情况下情况甚至更糟,因为任意(普遍量化的)Monad比实际更不可能解开IO


顺便说一句,ST您提到的变压器的实现方式与您建议的不同IOTST它使用as a State-like monad的内部实现,使用编译器提供的魔法精灵粉StateT特殊原语,并在此基础上定义 -like 转换器。IO在内部实现为更神奇ST的 ,因此IOT可以以类似的方式定义假设。

并不是说这真的会改变任何事情,除了可能让您更好地控制由IOT.

于 2012-10-24T20:17:20.540 回答