功能性程序设计:副作用实际发生在哪里?

在开始学习Haskell之后,即使在阅读了大量文档之后,我仍然在Haskell中不理解。

据我所知,要执行IO操作,您必须使用“IO monad”以“黑匣子”的形式包装值,以便使用IO monad的任何函数仍然是纯粹的功能。 好吧,很好,但是IO操作实际发生在哪里?

这是否意味着Monad本身并不是纯粹的功能? 或者是IO操作实现了,比方说C语言,并且在Haskell编译器中“嵌入”?

我可以使用纯粹的Haskell写或不写Monad,这可以做IO操作吗? 如果不是,如果语言本身不可能,这种能力从何而来? 如果它在Haskell编译器内嵌入/链接到C代码块,IO Monad是否最终会调用它来执行“脏作业”?


作为前言,尽管有许多写得不好的介绍,但它不是“ IO Monad ”。 这只是“ IO类型”。 单子没有什么神奇的。 Haskell的Monad类是一个非常无聊的东西 - 它只是比大多数语言可以支持的不熟悉和抽象。 即使IO实现了Alternative ,你也不会看到任何人称IOIO Alternative ”。 过度关注Monad只会影响学习。

在纯语言中原则性处理效果(而非副作用!)的概念魔术完全是IO类型的存在。 这是一个真正的类型。 这不是一个国旗说“这是不纯的!”。 这是一个完整的Haskell类型* -> * ,就像Maybe[] 。 输入接受IO值作为参数的签名,如IO a -> IO (Maybe a) ,这是合理的。 输入嵌套IO的签名是有意义的,如IO (IO a)

所以如果它是一个真正的类型,它必须有一个具体的含义。 Maybe a作为一个类型代表类型的可能缺失值a[a]表示类型为a 0个或更多个值。 IO a装置的产生类型的值的影响的序列a

请注意, IO的整个目的是表示一系列效果。 正如我上面所说,他们不是副作用。 它们不能隐藏在程序的无伤大雅的叶子中,神秘地改变其他代码背后的东西。 相反,由于它们是一个IO值,所以效果被明确地调出。 这就是为什么人们试图使用IO类型来最小化他们程序的一部分。 你在那里做的越少,在远处干扰你的程序的怪异行为的方式越少。

至于你的问题的主要内容,那么 - 一个完整的Haskell程序是一个名为mainIO值,以及它使用的定义集合。 编译器在生成代码时,插入一个确实非Haskell代码块,它实际上运行IO值中的效果序列。 从某种意义上说,这就是Simon Peyton Jones(GHC的长期作者之一)在他的演讲中得到Haskell无用的东西。

确实,无论实际执行IO操作如何,都不能保持概念上的纯粹。 (这里有一个非常不纯的函数来运行在Haskell语言中暴露的IO操作,我不会再多说它,而是添加它来支持外部函数接口,并且使用它不正确会严重地破坏你的程序。)但是Haskell的重点是为效果系统提供一个原则性的接口,并隐藏无原则的位。 而且它在实践中确实非常有用。

链接地址: http://www.djcxy.com/p/80877.html

上一篇: Functional programming : Where does the side effect actually happen?

下一篇: In what sense is IO monad special (if at all)?