Haskell中的所有图形和网络库如何实现?
我只开始学习Haskell。 我读过它是一种纯粹的函数式语言,其中的一切都是不变的。 因此,诸如输入输出,写入和读取数据库等事情会导致状态的可变性。 我知道Haskell中有一个叫做monad的东西,它允许像IO Monad
一样使用Haskell中的命令式功能。 但我很感兴趣的是Haskell中的一切都是在单子的帮助下实现的? 在HackageDB上,有很多包可以处理3D图形,数据库,解析HTML,编写Web服务器等等。
这一切背后的总体思路是什么? 什么让Haskell保持纯粹同时适用于编写所有这些? 我希望有人会为我明确这一点。 提前致谢!
我用以下类比来理解这些东西,我将用JavaScript来表达这些东西。
如何表达一个副作用计算?
1.功能
这显然是首要考虑的事情:
var launchRockets = function () {
prepareRockets( queryDBForPreparationParameters() )
launchAllPreparedRockets()
outputResults()
}
你可以看到一个有效的函数调用一堆其他有效的函数,它们本身可以产生未知的效果,并带来所有后果。
2.说明
表达这一点的另一种方式是编写一组指令,描述某些功能的有效计算以便稍后执行。 (曾经编写过一个SQL查询?)
var launchRocketsInstructions = [
{
description: "Prepare rockets",
parameters: {
description: "Query a DB for preparation parameters"
}
},
{
description: "Launch all prepared rockets"
},
{
description: "Output results"
}
]
那么我们在第二个例子中看到了什么? 我们看到描述计算的不可变数据树,而不是马上执行。 这里没有任何副作用,为了编写这个数据树,我们肯定可以使用纯函数。 这就是Haskell本质上的副作用。 语言提供的所有基础设施:monads, IO
, do
-notation - 这些只是工具和抽象,简化了您编写单一指令树的任务。
当然,要实际执行这些指令,人们最终必须逃避到野外的副作用世界。 在JavaScript的情况下,它会是这样execute(launchRocketsInstructions)
在Haskell的情况下,执行你生产出功能指令树的根运行main
主模块,它成为你的程序的单一入口点。 因此,Haskell的副作用实际上发生在语言范围之外,这就是为什么它是纯粹的。
我读过它是一种纯粹的函数式语言,其中的一切都是不变的。
Haskell只是纯粹的/默认情况下。 如果您向编译器声明(通过一元类型)您希望获得特定效果,则会启用它们。
他们只是默认情况下不开启。
在Haskell中,你永远不会执行任何事情。 您只需将IO操作组合起来,然后将该描述分配给main,即可构建您想要执行的操作的描述。 然后编译器将它在主变量中找到的任何程序描述转换为可执行代码。
我建议你阅读我写的Haskell IO的这个介绍,它更详细地描述了事情。
但是,这只解释了我们如何结合IO操作而不是如何引入新操作。 Haskell有两种方法来添加新的IO操作:
然后,所有IO monad所做的就是将这些原始IO操作组合成更大的IO操作。
链接地址: http://www.djcxy.com/p/14195.html上一篇: How are all graphic and web libraries implemented in Haskell?