На этом шаге мы рассмотрим процесс моделирования таких вычислений.
f(⊥) = ⊥
Библиотечные функции C являются строгими функциями.
Для простой демонстрации "ленивости" языка Haskell воспользуемся функциями, позволяющими моделировать неопределённое значение.
Неопределённое значение (в языке Haskell) моделируется с помощью функций
error и undefined,
Prelude>: t error Prelude> :t undefined error :: String -> a undefined :: a
Например:
Prelude> "123"++error "1" "123 Program execution error: 1
1. Prelude> head ['a',error "123"] 'a' :: Char => head('a',⊥)='a' Prelude> head ['a',undefined] 'a' :: Char => head('a',⊥)='a' Prelude> (\ x _ -> x) 1 (error "123") 1 :: Integer => (\ x _ -> x)(1,⊥)=1
2. Prelude> tail ['a',error "123"] " Program execution error: 123 => tail('a',⊥)=⊥ Prelude> tail ['a',undefined] " Program execution error: {undefined} => tail('a',⊥)=⊥ Prelude> tail (tail ['a',error "123"]) "" :: [Char] => tail(tail('a',⊥))=""
Итак, если есть необходимость в вычислении значения второго элемента списка, то он, естественно, будет вычисляться.
Таким образом, язык Haskell осуществляет вычисления, интерпретируя равенства в большей степени как объявления (или определения), чем присваивания, встречающиеся в языках императивного программирования.
Например, интерпретация определения
x=1/0
Программирование с использованием присваиваний требует пристального внимания за соблюдением порядка присваиваний: смысл программы зависит от порядка, в котором эти присваивания выполняются.
На следующем шаге мы рассмотрим моделирование строгих вычислений .