Способ выполнения кода по умолчанию на Haskell - PullRequest
6 голосов
/ 03 января 2012

В следующем обобщенном коде:

nat = [1..xmax]
xmax = *insert arbitrary Integral value here*   

setA = [2*x | x <- nat]
setB = [3*x | x <- nat]

setC = [4*x | x <- nat]
setD = [5*x | x <- nat]

setOne = setA `f` setB
setTwo = setC `f` setD

setAll = setOne ++ setTwo

setAllSorted = quicksort setAll

(обратите внимание, что 'f' обозначает функцию типа

f :: Integral a => [a] -> [a] -> [a] 

это не просто ++)

как Haskell обрабатывает попытку печати setAllSorted?

Получает ли он значения для setA и setB, вычисляет setOne, а затем сохраняет только значения для setOne в памяти (до вычисления всего остального)?

Или Haskell хранит все в памяти, пока не получит значение для setAllSorted?

Если последнее имеет место, то как мне указать (используя main, do do функции и все остальное, что касается ввода-вывода), что вместо этого он выполняет первый?

Могу ли я сообщить программе, в каком порядке вычислять и собирать мусор? Если так, то как бы я это сделал?

Ответы [ 2 ]

9 голосов
/ 03 января 2012

Голова setAllSorted обязательно меньше или равна каждому элементу в хвосте. Поэтому, чтобы определить голову, все setOne и setTwo должны быть вычислены. Кроме того, поскольку все наборы являются постоянными аппликативными формами, я считаю, что они не будут собираться мусором после вычисления. Сами числа, скорее всего, будут разделены между наборами, но узлы, которые их склеивают, скорее всего, не будут (ваша удача с некоторыми из них будет зависеть от определения f).

7 голосов
/ 03 января 2012

Из-за лени Haskell оценивает вещи по требованию.Вы можете думать о печати, выполненной в конце, как о «вытягивании» элементов из списка setAllSorted, и это может потянуть за собой другие вещи.

То есть, запустив этот код, он будет выглядеть примерно так:

  1. При печати сначала оценивается первый элемент setAllSorted.
  2. Поскольку это происходит из-за процедуры сортировки, для оценки всех элементов setAll потребуется выполнить оценку.(Поскольку самый маленький элемент может быть последним).
  3. Оценка первого элемента setAll требует оценки первого элемента setOne.
  4. Оценка первого элемента setOneзависит от того, как f реализовано.Может потребоваться оценка всех или ни одного из setA и setB.
  5. После того, как мы закончим печать первого элемента setAllSorted, setAll будет полностью оценен.Больше нет ссылок на setOne, setTwo и меньшие наборы, так что теперь все они имеют право на сборку мусора.Первый элемент setAllSorted также может быть восстановлен.

Таким образом, теоретически этот код будет хранить setAll в памяти большую часть времени, тогда как setAllSorted, setOne и setTwo вероятно, будет занимать только постоянное количество места в любое время.В зависимости от реализации f, то же самое может быть верно для меньших наборов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...