Отключить ленивую оценку в haskell
Можно ли отключить ленивую оценку в Haskell?
Есть ли специальный флаг компилятора библиотеки для облегчения этого?
Я хотел попробовать что-то новое со старой программой, которую я написал некоторое время назад, чтобы узнать, могу ли я повысить производительность.
Ответы
Ответ 1
Есть несколько способов превратить ленивую вещь в строгую. Вы можете:
- Явно вставить совпадение паттерна.
- Используйте
seq
или его близкий родственник ($!)
.
- Используйте
BangPatterns
.
- Используйте аннотации строгости для ваших типов.
Подробнее здесь.
Ответ 2
Вы не можете отключить лень, потому что от этого зависит система ввода-вывода Haskell. Без ленивой оценки эта программа запускается в цикл занятости, не выводя ничего:
main = forever (putStrLn "Hello!")
Это потому, что forever c
- бесконечная программа. При ленивой оценке программа рассчитывается только по мере необходимости для выполнения следующей инструкции. Если вы отключите лень, каждая функция станет строгой, в том числе (>>)
, которая в основном заставляет функцию forever
расходиться:
forever c = let cs = c >> cs in cs
Однако вы можете добавить аннотации строгости к конструкторам и шаблонам. Когда функция является строгой, ее аргумент принудительно рассматривается как часть оценки результата независимо от того, нужен ли аргумент или нет. Это похоже на нетерпеливую оценку.
Ответ 3
В дополнение к тому, что перечислял Даниэль Вагнер, вы можете взглянуть на аналогичный вопрос Есть ли компилятор или препроцессор Haskell, который использует строгую оценку?.
- Ответы включают компилятор DDC, который пытается сделать строгую версию haskell и только ленив явно
- ghc plugin, описанный в monad.reader 12
- "Использование nfdata и rnf всюду" - solrize
- и более
Основное предложение состоит в том, чтобы использовать инструменты профилирования и узнать, как оптимизировать Haskell, поскольку это, однако, так как большинство рассмотрит его на другом языке с выключенной нестрогой оценкой.
Ответ 4
Там вариант Haskell называется pH (http://csg.csail.mit.edu/projects/languages/ph.shtml)
который использует нетерпеливую оценку, сохраняя при этом нестрогую семантику. В отчете Haskell очень важно сказать, что это нестрогий язык. Лень - это очевидный способ описать и, по-видимому, реализовать нестрогость.
Итак, если ваш вопрос: "Можем ли мы использовать другую систему оценки при сохранении нестрогой семантики", вы можете посмотреть на значение pH. Если у вас есть вопрос: "Существует ли версия Haskell, которая разделяет поверхностный синтаксис, но по умолчанию строит строго", я думаю, что она была покрыта другими ответами.
Ответ 5
Вы можете включить прагму Strict
в модуле, что по умолчанию будет строго по умолчанию.
https://ghc.haskell.org/trac/ghc/wiki/StrictPragma
Ответ 6
Простой ответ - нет. Более сложный ответ заключается в том, что вычислительная модель, на которой Haskell строит и оценивает функции, работает ленивым образом. Как вы прочтете в другом ответе, есть способы заставить оценивать некоторые функции раньше, чем обычно, и иногда это бывает случайным образом. Но есть большая часть действительного Haskell, который не имеет нормальной формы. Это включает в себя функции ввода-вывода и большое количество стандартной прелюдии.
Заключение: в Haskell больше нет способа превратить ленивую оценку, тогда есть способ отключить арифметику указателя на C или отключить OO в Ruby Java. Я подозреваю, что это намного дальше, чем вы, хотя этот вопрос возьмет вас. (Нет режима --strict
), но если вы действительно хотите увидеть, насколько глубока ядро рабита, " Внедрение" ленивых функциональных языков "на складе Оборудование:" Без спины "Tagless G-machine" Саймон Пейтон Джонс - это приключение, заслуживающее внимания.
Ответ 7
Пакет strict-identity
имеет строгую версию монады Identity
.
Вы можете найти его здесь:
https://hackage.haskell.org/package/strict-identity
Использование будет выглядеть примерно так:
foo = runStrictIdentity $! do
x <- f a b
y <- g x y
return $! x + y
Каждый раз, когда используется return
или bind >>=
, эти две части оцениваются с помощью seq
, что дает разумную гарантию строгости, если ваша структура данных не слишком глубока. Это работает, например, для чисел и базовых структур.