На этом шаге мы рассмотрим процесс моделирования таких вычислений.
В языке Haskell существует строгая функция seq, которая имеет следующую сигнатуру типа:
Prelude> :t seq seq :: a -> b -> b
Другими словами, функция seq определена следующим образом:
seq(⊥,b)=⊥; seq(a,b)=b, если a≠⊥.
Первый аргумент вычисляется, как обычно, лишь до слабой заголовочной нормальной формы (англ. "weak head normal form"); например, слабой заголовочной нормальной формой для [1..] является 1:_.
(а) Prelude> seq 1 sin 3
0.14112 => seq(1,sin(3))=0.14112
(б) Prelude> seq (sin 4) 5
5 :: Integer => seq(sin(4),5)=5
(в) Prelude> seq [1..] 5
5 :: Integer => seq([1..],5)=5
(г) Prelude> seq (length [1..]) 5
"CTRL+Break" => 1 не завершаются 0...
(д) Prelude> seq (error "123") 5
Program execution error: 123 => seq(⊥,5)=⊥
(е) Prelude> seq 1 "3"++(error "2")
"3
Program execution error: 2 => seq(1,⊥)=⊥
(ж) Prelude> seq ("0"++error "1")
("0"++error "2")
"0
Program execution error: 2 => seq(⊥,⊥)=⊥
Ещё одним способом моделирования строгих вычислений в языке Haskell является использование операции строгой аппликации ($!), которая определяется так:
f $! x = x `seq` (f x)
Напомним, что операция нестрогой аппликации ($) определяется следующим образом:
f $ x = f x
На следующем шаге мы рассмотрим конструирование потенциально бесконечных списков с помощью корекурсии.