Как все графические и веб-библиотеки реализованы в Haskell?

Я только начинаю изучать Haskell. Я читал, что это чисто функциональный язык, и все в нем является неизменным. Таким образом, такие вещи, как ввод, вывод и запись баз данных, вызывают изменчивость состояния. Я знаю, что в Haskell есть такая вещь, как монады, которые позволяют использовать императивные функции в Haskell, такие как IO Monad, Но мне интересно, все ли императивно в Haskell реализовано с помощью монад? На HackageDB есть много пакетов, которые позволяют работать с 3d-графикой, базами данных, анализировать HTML, писать веб-серверы и так далее и тому подобное.

Какая общая идея стоит за всем этим? Что позволяет Haskell оставаться чистым и одновременно подходящим для написания всего этого? Я надеюсь, что кто-нибудь прояснит это для меня. Заранее спасибо!

4 ответа

Решение

Я понял эти вещи, используя следующую аналогию, которую я изложу с помощью 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. Вся инфраструктура, которую обеспечивает язык: монады, IO, do-notation - это всего лишь инструменты и абстракции, упрощающие задачу составления единого дерева инструкций.

Конечно, чтобы действительно выполнить эти инструкции, нужно в конечном итоге сбежать в дикий мир побочных эффектов. В случае JavaScript это было бы что-то вроде execute(launchRocketsInstructions), в случае Haskell это среда выполнения, выполняющая корень дерева команд, которое вы производите с помощью функции main основного модуля, который становится единой точкой входа вашей программы. Таким образом, побочные эффекты в Haskell на самом деле возникают вне языковой области, поэтому они чистые.

Я читал, что это чисто функциональный язык, и все в нем является неизменным.

Haskell только чистый / по умолчанию /. Если вы объявляете компилятору (через монадический тип), что вы хотите иметь определенные эффекты, тогда они включены.

Они просто не включены по умолчанию.

В Хаскеле вы никогда ничего не исполняете. Вы просто создаете описание того, что вы хотите сделать, комбинируя действия ввода-вывода, а затем назначаете это описание main. Затем компилятор переводит любое найденное в основной переменной описание программы в исполняемый код.

Я рекомендую вам прочитать это введение в Haskell IO, которое я написал, в котором все изложено более подробно.

Однако это только объясняет, как мы объединяем действия ввода-вывода, а не то, как мы вводим новые. У Haskell есть два способа добавить новые действия ввода-вывода:

  • Встроенные компиляторы
  • Интерфейс внешней функции (FFI)

Тогда все, что делает монада IO - это объединяет эти примитивные действия IO в более крупные действия IO.

Да, все, что необходимо в Хаскеле, написано с помощью монад. Монады - это общая идея, которая позволяет Haskell быть как чистым, так и применимым для написания практических программ, которые выполняют реальный ввод-вывод.

Я рекомендую прочесть известную статью Саймона Пейтона Джонса "Tackling the Awkward Squad", в которой объясняется, как монада IO используется для программирования в реальном мире на чисто функциональном языке.

Другие вопросы по тегам