![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Хорошая хотя и простая задачка возникла в процессе проверки домашних заданий. Чем отличается поведение следующих двух функций, и в чем причина такого отличия:
diff xs = do p <- zip xs (tail xs) return $ abs (fst p - snd p) diff' xs = do p <- zip (tail xs) xs return $ abs (fst p - snd p)
no subject
Date: 2014-04-15 06:29 am (UTC)no subject
Date: 2014-04-15 06:59 am (UTC)Разница в том, что diff' [] вычисляет сначала tail [] и отваливается с ошибкой.
Т.е. у zip только второй аргумент лениво вычисляется.
no subject
Date: 2014-04-15 02:56 pm (UTC)Дело в том, что сопоставление с образцом всегда делается сверху вниз (по уравнениям) и слева направо (по образцам-параметрам текущего уравнения). Поэтому, если первый в текущем уравнении образец представлен конструктором, то для сопоставления соответствующий параметр передаваемый в функцию должен быть приведен в WHNF. А у zip оказывается так, что если WHNF - это пустой список, то выбирается второе уравнение, которому пофиг на второй аргумент.
no subject
Date: 2014-04-15 03:49 pm (UTC)Т.е. (если я правильно пользуюсь терминами) zip всегда строгий по первому агрументу, и иногда не строгий по второму. А сопоставление с образцом -- это причина строгости/нестрогости.
no subject
Date: 2014-04-15 05:27 pm (UTC)Раньше take была строгая по первому аргументу, а стала "иногда нестрогая":
Но понятно, что это же совершенно маргинальное улучшение!
no subject
Date: 2014-04-15 09:28 am (UTC)А нетотальные языки это вообще языки?
no subject
Date: 2014-04-15 10:03 am (UTC)