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

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.

  • @David:取决于你如何看待它.如果`IO`真的是一个状态值为整个外部世界的`State` monad,则定义为这样的`IOT`将正常工作,其中"正确"意味着`IOT Maybe`中的`Nothing`会丢弃宇宙,从而结束所有存在.就个人而言,我会坚持目前的情况...... (18认同)
  • 这是为了*如何*运行*一个特定实现的IO计算错误. (2认同)
  • `IOT (Just m) >>= k = IOT $ Just $ m >>= 也许 (fail "...") id 怎么样。运行物联网。k`?这很糟糕,因为`(>>=)` 可以`失败`(当它不应该时)? (2认同)
  • Soo... 问题的真正根源在于,我们无法从“Nothing :: Maybe a”中变出一个“a”,我们可以“返回”然后“加入”,对吗?显然,这将适用于“身份”,但是否还有其他可能适用的单子? (2认同)