首页 文章

如何在Haskell中实现所有图形和Web库?

提问于
浏览
5

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

这一切背后的一般理念是什么?是什么让Haskell保持纯粹并同时适用于写这一切?我希望有人能为我说清楚 . 提前致谢!

4 回答

  • 3

    我使用以下类比来理解这些内容,我将用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中的副作用实际上发生在语言范围之外,即's why it' s纯 .

  • 0

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

    Haskell只是纯/默认/ . 如果您向编译器声明(通过monadic类型)您希望具有某些效果,则启用它们 .

    它们默认情况下不会打开 .

  • 12

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

    我建议你阅读这篇introduction to Haskell IO我写了更详细的解释 .

    但是,这只能解释我们如何组合IO操作而不是如何引入新操作 . Haskell有两种方法可以添加新的IO操作:

    • 编译器内置函数

    • 外部函数接口(FFI)

    然后,所有IO monad都会将这些原始IO操作组合成更大的IO操作 .

  • 8

    是的,Haskell中的所有必要条件都是在monad的帮助下编写的 . Monads是一般的想法,它允许Haskell既纯粹又适用于编写实际I / O的实用程序 .

    我建议阅读Simon Peyton Jones撰写的着名论文"Tackling the Awkward Squad",其中解释了如何使用IO monad以纯函数语言进行实际编程 .

相关问题