【问题标题】:How are all graphic and web libraries implemented in Haskell?Haskell 中的所有图形和网络库是如何实现的?
【发布时间】:2013-04-05 13:15:46
【问题描述】:

我才开始学习 Haskell。我读过它是一种纯函数式语言,其中的所有内容都是不可变的。因此,诸如输入输出、写入和读取数据库之类的事情会导致状态的可变性。我知道 Haskell 中有一个叫做 monads 的东西,它允许在 Haskell 中使用命令式特性,比如 IO Monad。但我很感兴趣的是,Haskell 中所有必要的事情都是在 monad 的帮助下实现的吗?在 HackageDB 上有很多包可以处理 3d 图形、数据库、解析 HTML、编写 Web 服务器等等。

这一切背后的总体思路是什么?是什么让 Haskell 保持纯粹并同时适用于编写所有这些?我希望有人会为我澄清这一点。提前致谢!

【问题讨论】:

    标签: haskell functional-programming monads hackage


    【解决方案1】:

    我通过下面的类比来理解这些东西,我将用 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 中副作用的本质所在。该语言提供的所有基础架构:monad、IOdo-notation - 这些只是工具和抽象,可简化您编写单个指令树的任务。

    当然,要真正执行这些指令,最终必须逃入副作用的狂野世界。在 JavaScript 的情况下,它类似于execute(launchRocketsInstructions),在 Haskell 的情况下,它是执行指令树根的运行时,您使用主模块的函数 main 生成,它成为您的单一入口点程序。因此 Haskell 中的副作用实际上发生在语言范围之外,这就是为什么它是纯粹的。

    【讨论】:

      【解决方案2】:

      我读到它是一种纯函数式语言,其中的所有内容都是不可变的。

      Haskell 只是纯粹的/默认情况下/。如果您向编译器声明(通过一元类型)您希望产生某些效果,那么它们就会被启用。

      它们只是默认不开启。

      【讨论】:

        【解决方案3】:

        在 Haskell 中,您永远不会真正执行任何操作。您只需通过组合 IO 操作来构建您希望执行的操作的描述,然后将该描述分配给 main。然后编译器将它在主变量中找到的任何程序描述转换为可执行代码。

        我建议您阅读此introduction to Haskell IO 我写的内容更详细。

        但是,这仅说明了我们如何组合 IO 操作,而不是我们如何引入新操作。 Haskell 有两种方式来添加新的 IO 动作:

        • 编译器内置
        • 外部函数接口 (FFI)

        那么 IO monad 所做的就是将这些原始 IO 动作组合成更大的 IO 动作。

        【讨论】:

          【解决方案4】:

          是的,Haskell 中所有必要的东西都是在 monad 的帮助下编写的。 Monad 是允许 Haskell 既纯粹又适用于编写执行实际 I/O 的实用程序的一般思想。

          我推荐阅读 Simon Peyton Jones 的著名论文 "Tackling the Awkward Squad",其中解释了如何使用 IO monad 以纯函数式语言进行实际编程。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-01-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-10-17
            • 2018-05-22
            相关资源
            最近更新 更多