Я часто читаю, что lazy - это не то же самое, что не строгий , но мне трудно понять разницу.Они кажутся взаимозаменяемыми, но я понимаю, что они имеют разные значения.Буду признателен за помощь в понимании разницы.
У меня есть несколько вопросов, которые разбросаны по этому посту.Я суммирую эти вопросы в конце этого поста.У меня есть несколько примеров фрагментов, я их не тестировал, я только представил их как концепции.Я добавил цитаты, чтобы вы не искали их.Может быть, это поможет кому-то позже с тем же вопросом.
Non-Strict Def:
Функция f называется строгой, если при применении к неопределенному выражению онатакже не в состоянии прекратить.Другими словами, f строгое, если значение f bot равно | .Для большинства языков программирования все функции являются строгими.Но это не так в Хаскеле.В качестве простого примера рассмотрим const1, функцию константы 1, определяемую следующим образом:
const1 x = 1
Значение бота const1 в Haskell равно 1. С практической точки зрения, поскольку const1 этого не делает "нужно "значение его аргумента, он никогда не пытается его оценить, и, следовательно, никогда не попадает в непрерывное вычисление.По этой причине нестрогие функции также называются «ленивыми функциями» и, как говорят, оценивают свои аргументы «лениво» или «по необходимости».
- A Нежное введение вHaskell: Функции
Мне очень нравится это определение.Кажется, это лучшее, что я мог найти для строгого понимания.const1 x = 1
также ленив?
Нестрогость означает, что сокращение (математический термин для оценки) происходит извне,
, так что если у вас есть (a + (b c)) затем сначала вы уменьшаете +, затем вы уменьшаете внутреннее (b c).
- Haskell Wiki: Lavy vs nonsrict
Haskell Wiki действительно смущает меня.Я понимаю, что они говорят о порядке, но я не вижу, как (a+(b*c))
будет оценивать не строго, если он был передан _|_
?
При нестрогом вычислении аргументы функциине оценивается, если они фактически не используются при оценке тела функции.
При кодировании по Церковью ленивая оценка операторов переводится в нестрогую оценку функций;по этой причине нестрогая оценка часто упоминается как "ленивая".Булевы выражения во многих языках используют форму нестрогого вычисления, называемого оценкой короткого замыкания, когда оценка возвращается, как только может быть определено, что однозначный логический результат будет получен - например, в дизъюнктивном выражении, где встречается истина, или вконъюнктивное выражение, где встречается ложь, и так далее.В условных выражениях также обычно используется отложенная оценка, когда оценка возвращается, как только получится однозначная ветвь.
- Википедия: Стратегия оценки
Ленивая защита:
Ленивая оценка, с другой стороны, означает оценку выражения только тогда, когда необходимы его результаты (обратите внимание на переход от «сокращения» к «оценке»).Поэтому, когда механизм оценки видит выражение, он создает структуру данных thunk, содержащую любые значения, необходимые для оценки выражения, плюс указатель на само выражение.Когда результат действительно необходим, механизм оценки вызывает выражение, а затем заменяет блок на результат для дальнейшего использования....
Очевидно, что между выражением thunk и частично оцененным выражением существует сильная связь.Следовательно, в большинстве случаев термины «ленивый» и «нестрогий» являются синонимами.Но не совсем.
- Haskell Wiki: Lavy против нестрогих
Это похоже на конкретный ответ на Haskell. Я полагаю, что ленивый означает гром, а не строгий означает частичную оценку. Это сравнение слишком упрощено? Означает ли ленивый всегда значительный разброс, а нестрогий всегда означает частичную оценку.
В теории языка программирования ленивая оценка или вызов по требованию 1 - это
стратегия оценки, которая задерживает оценку выражения
пока его значение фактически не требуется (не строгая оценка), а также
избегать повторных оценок (обмена).
- Википедия: Ленивая оценка
Императивные примеры
Я знаю, что большинство людей говорят, что забывают об обязательном программировании при изучении функционального языка. Тем не менее, я хотел бы знать, квалифицируются ли они как нестрогие, ленивые, оба или нет? По крайней мере, это дало бы что-то знакомое.
Короткое замыкание
f1() || f2()
C #, Python и другие языки с "yield"
public static IEnumerable Power(int number, int exponent)
{
int counter = 0;
int result = 1;
while (counter++ < exponent)
{
result = result * number;
yield return result;
}
}
- MSDN: выход (c #)
Callbacks
int f1() { return 1;}
int f2() { return 2;}
int lazy(int (*cb1)(), int (*cb2)() , int x) {
if (x == 0)
return cb1();
else
return cb2();
}
int eager(int e1, int e2, int x) {
if (x == 0)
return e1;
else
return e2;
}
lazy(f1, f2, x);
eager(f1(), f2(), x);
Вопросы * * 1111
Я знаю, что ответ прямо передо мной со всеми этими ресурсами, но я не могу понять его. Кажется, что определение слишком легко отклонить как подразумеваемое или очевидное.
Я знаю, у меня много вопросов. Не стесняйтесь отвечать на любые вопросы, которые вы считаете актуальными. Я добавил эти вопросы для обсуждения.
const1 x = 1
тоже ленивый?
Как оценка из "внутреннего" не строгая? Это потому, что внутрь допускается сокращение ненужных выражений, как в const1 x = 1
? Сокращения, кажется, соответствуют определению ленивых.
означает ли ленивый всегда thunks и нестрогий всегда означает частичная оценка ? Это просто обобщение?
Являются ли следующие императивные понятия ленивыми, нестрогими, обоими или нет?
Короткое замыкание
Использование доходности
Передача обратных вызовов, чтобы задержать или избежать исполнения
Является ли ленивым подмножеством нестрогих или наоборот, или они взаимоисключающие. Например, возможно ли быть нестрогим , не будучи ленивым , или ленивым , не будучи нестрогим ?
Достигнут ли лукавство несправедливости Хаскеля?
Спасибо, ТАК!