通过IO了解Haskell中的纯函数

Kev*_*ith 5 haskell

给出Haskell (根据Rein Heinrich评论编辑)f:

f :: IO Int
f = ... -- ignoring its implementation
Run Code Online (Sandbox Code Playgroud)

引用"Idris的类型驱动开发"

纯函数的关键属性是相同的输入总是产生相同的结果.此属性称为参照透明度

f,和,即IO ...Haskell中的所有函数,纯粹?在我看来,从那以后,它们lookInDatabase :: IO DBThing不会总是返回相同的值,因为:

  • 在t = 0时,DB可能会关闭
  • 在t = 1时,DB可能会启动并return MyDbThing导致结果

总之,是f(和IO ...一般的功能)纯粹?如果是,那么请纠正我的错误理解,因为我试图f用我的t=...例子反驳功能纯度.

Eri*_*lun 6

从概念上讲,IO实际上是一种单独的语言.它是Haskell RTS(运行时系统)的语言.它在Haskell中实现为(相对简单的)嵌入式DSL,其"脚本"具有该类型IO a.

因此返回类型值的Haskell函数IO a实际上不是在运行时执行的函数 - 执行的是IO a值本身.所以这些函数实际上纯粹的,但它们的返回值代表非纯计算.

从语言设计的角度来看,IO是一个非常优雅的黑客,可以将非纯粹的丑陋完全隔离开,同时将其紧密地融入其纯净的环境中,而不需要使用特殊的外壳.换句话说,该设计并不能解决由不纯IO引起的问题,但它至少不会影响代码的纯部分.


下一步是研究FRP - 使用FRP,您可以使包含IO的层更薄,并将更多非纯逻辑移动到纯逻辑中.

您可能还想阅读John Backus关于函数编程主题的着作,Von Neumann架构的局限性等.如果您对纯度和IO之间的关系感兴趣,Conal Elliott也是谷歌的名字.


PS也值得注意的是,虽然IO严重依赖monad来解决懒惰评估的问题,并且因为monad是构建嵌入式DSL的一种非常好的方式(其中IO只是一个例子),monad更加通用比IO,所以尽量不要在相同的上下文中考虑IO和monad - 它们是两个独立的东西,两者都可以存在而没有另一个.


344*_*442 5

首先,您注意到 I/O 操作不是纯粹的,这是正确的。这不可能。但是,所有函数的纯度是 Haskell 的一大亮点,那么到底发生了什么?

无论您是否喜欢,应用到具有IO Something某些参数的a (也可能被错误地称为“返回 a”)的函数始终返回IO Something具有相同参数的相同值。monadIO允许您将操作“隐藏”在 monad 所充当的容器内。当你有一个 时IO String,该函数/对象不包含/ String[Char]而是一种承诺,即你String将来会以某种方式得到它。因此,IO包含需要执行不纯 I/O 操作时要执行的操作的信息。

毕竟,IO执行操作的唯一方法是具有名称main,或者成为其依赖项main。由于 monad 的灵活性,您可以“连接”IO操作。像这样的程序...(注意:这段代码不是一个好主意)

main = do
    input <- getLine
    putStrLn input
Run Code Online (Sandbox Code Playgroud)

合成糖是...

main =
    getLine >>= (\input -> putStrLn input)
Run Code Online (Sandbox Code Playgroud)

这表明mainI/O 操作是通过将从标准输入读取的字符串打印到标准输出(后跟换行符)而产生的。你看到魔法了吗?IO只是一个包装器,表示在不纯的上下文中要做什么以产生一些给定的输出,但不是该操作的结果,因为这需要 Haskell 语言承认不纯的代码。

把它想象成一种收据。如果你有一个蛋糕的收据(阅读:IOmonad)(阅读:Somethingin IO Something),你知道如何制作蛋糕,但你无法制作蛋糕(因为你可以搞砸那个杰作)。相反,Master Chief(读:Haskell 运行时系统的最基本部分,负责应用main)为你做肮脏的工作(读:做不纯/非法的事情),而且,最重要的是,他不会犯任何错误(阅读:破坏代码纯度)......当然除非烤箱坏了(阅读:)System.IO.Error,但他知道如何清理它(阅读:代码将永远保持纯净)。

IO这是不透明类型的原因之一。它的实现有些争议(直到您阅读 GHC 的源代码),并且最好保留为实现定义的。

只要快乐就好,因为你已经被纯洁照亮了。很多程序员甚至不知道 Haskell 的存在!

我希望这对你有所启发!