Прежде всего, следует иметь в виду некоторые важные общие сведения:
Переменные Haskell неизменны .
Всегда, без исключения, и вы ничего не можетеделать с этим.
Поэтому, когда вы пишете что-то вроде let y = 5
, никогда не изменяет значение какой-либо уже существующей переменной. Скорее, он вводит новую переменную с именем y
и дает ей желаемое значение. Где-нибудь еще в вашей программе есть переменная, которую вы назвали y
, не имеет значения, это вообще другая переменная. Фактически, учтите следующее:
main :: IO ()
main = do
let y = 1
do let y = 2
print y
print y
Вывод:
2
1
В вашем примере оператор let y = 5
вообще не имеет никакого эффекта и, скорее всего, будет просто отброшенкомпилятор вообще. Фактически, если вы скомпилируете с -Wall
(как следует), GHC сообщит вам, что:
/tmp/wtmpf-file30239.hs:4:7: warning: [-Wunused-local-binds]
Defined but not used: ‘y’
|
4 | let y = 5
| ^
Так, в частности, проверка y == 8
не может быть затронута каким-либо оператором let y =
Вы могли бы использовать.
На самом деле, в общем, ленивая оценка не влияет на значения. Это одна из замечательных особенностей чисто функционального языка: поскольку все постоянно, ленивая оценка, как правило, не влияет на семантику значений, она влияет только на порядок, в котором выполняется та же самая работа - что может влияет на то, как быстро что-то завершается (или заканчивается ли оно вообще), но не на то, какое значение оно производит, когда оно сделано. Не имеет значения, оценивается ли y == 8
до или после того, как среда выполнения входит в функцию test
, и на самом деле стандарт Haskell ничего об этом не говорит - все, что он говорит, это то, что если test
заканчивается даже если не использовать значение аргумента, то не определяющий аргумент не должен препятствовать завершению test
( не строгая семантика ). Итак, следующее демонстрирует ленивую оценку в действии:
unobtanium :: Bool
unobtanium = unobtanium -- infinite loop
don'tTest :: Bool -> IO ()
don'tTest a = do
putStrLn "Meh, I'm too lazy to do it."
main :: IO ()
main = do
let y = unobtanium
don'tTest y
... даже если y
невозможно оценить.