Нелинзовая ветвь GHC

Я слышал, что есть ветвь GHC, которая по умолчанию компилируется в строгий код, тогда как ленту можно включить аннотацией. (IIRC, он сказал, что финансовая компания развивает отрасль и использует ее для производственного кода.) Это правда? Я не могу найти его.

Человек также предположил, что мнение о том, что строгая оценка более практична, чем ленивая оценка (по умолчанию), все больше принимает признание. Я не нашел это подтвержденным в списке рассылки Haskell, но, может быть, это потому, что люди не придерживаются такой практики?

Все, что я нахожу в строгом Haskell, - это такие вещи, как $! и rnf. Хотя я считаю, что ленивая оценка очень элегантная, я хотел бы разработать программу в Haskell, где я хочу избежать утечек пространства и хотел бы иметь предсказуемую производительность.

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

Ответ 1

Вы ищете Disciple.

Таким образом, в Haskell есть два типа лени. Там ленивый ввод-вывод, который является мерзостью и решается с помощью итерационных библиотек (бесстыдная плагин: включая мою pipes). Тогда там лень в чистых вычислениях, которые все еще открыты для обсуждения, но я постараюсь обобщить основные преимущества лени, так как вы уже знакомы с недостатком:

Лень более эффективна

Простой пример:

any = foldr (||) False

any находит, если любое значение в списке True. Это оценивает только элементы до первого True, поэтому не имеет значения, слишком ли длинный список.

Лень вычисляет столько, сколько нужно, что означает, что если вы объедините два ленивых вычисления, это может фактически улучшить временную сложность результирующего вычисления. Этот комментарий о переполнении стека дает еще один хороший пример этого.

Это фактически та же самая причина, почему итерационные библиотеки очень эффективны с точки зрения ресурсов. Они выполняют столько же работы, сколько и при создании результатов, что приводит к очень эффективному использованию памяти и диска с очень простой в использовании семантикой.

Лень по своей природе более сложна

Это хорошо известно людям, которые запрограммировали как на строгих, так и на функциональных языках, но я на самом деле случайно продемонстрировал ограниченное доказательство этого при работе с библиотекой pipes, где ленивая версия является единственной версией, которая разрешает Category. Трубы действительно работают в любой монаде, включая чистую монаду Identity, поэтому мои доказательства переводят и на чистый код.

Это истинная причина, по которой я считаю, что лень в целом - это будущее программирования, но я все же думаю, что это открытый вопрос о том, осуществил ли Haskell ленивость "правильно".

Ответ 2

Похоже, вы слышали про Роберта Энналса кандидатскую диссертацию по спекулятивной оценке с GHC. Он создал вилку GHC под названием "spec_eval", где была сделана спекулятивная оценка. Поскольку Haskell является нестрогим, а не явно ленивым, spec_eval был строгим вплоть до того момента, когда он фактически изменил ситуацию. Хотя во всех случаях он был быстрее, он требовал больших изменений в GHC и никогда не сливался.

Этот вопрос имеет ответ на этот вопрос на этом сайте.

Ответ 3

Некоторые хорошие вещи были сказаны о том, почему вы не должны уклоняться от лени Haskell, но я чувствую, что исходный вопрос остается без ответа.

Функция приложения в Haskell не является строгой; то есть аргумент функции оценивается только при необходимости.

~ Haskell Report 2010 > Предопределенные типы и классы # Строгая оценка

Это немного вводит в заблуждение. Реализации могут оценивать аргументы функции до того, как они потребуются, но только в ограниченной степени. Вы должны сохранить нестрогую семантику: поэтому, если выражение для аргумента приводит к бесконечному циклу, и этот аргумент не используется, то вызов функции с этим аргументом не должен иметь бесконечного цикла.

Итак, вам разрешено реализовать Haskell таким образом, который не является полностью "ленивым", но тем не менее он не может быть "строгим". Это кажется противоречием с первого взгляда, но это не так. Несколько связанных тем, которые вы можете проверить:

Ответ 4

Если я правильно понимаю, строгий Haskell не может иметь монадического ввода-вывода, как мы его знаем. Идея в Haskell заключается в том, что весь код Haskell является чистым (который включает в себя действия IO, которые работают как государственная монада), а "main" дает значение типа IO() для среды выполнения, которая затем многократно воздействует на оператор последовательности → =,

Для контрапункта к сообщению Tekmo вы можете посмотреть блог Роберта Харпера, * http://existentialtype.wordpress.com/2011/04/24/the-real-point-of-laziness/ и связанных. Это происходит в обоих направлениях.

По моему опыту, сначала ленивость трудна, но потом вы привыкаете к ней, и это прекрасно.

Классическая пропагандистская статья для лености - это статья Хьюза "Почему вопросы функционального программирования", которую вы должны легко найти.