52700.fb2
even (Succ Zero) = res
where res = False
even x = even res
where (Succ (Succ res)) = x
Конечно в этом примере where не нужны, но здесь они приведены для иллюстрации привязки where-
выражения к данному уравнению. Мы определили три локальных переменных с одним и тем же именем.
where-выражения могут быть и у значений, которые определяются внутри where-выражений. Но лучше
избегать сильно вложенных выражений.
60 | Глава 4: Декларативный и композиционный стиль
let-выражения
В композиционном стиле функция вычисления площади треугольника будет выглядеть так:
square a b c = let p = (a + b + c) / 2
in
sqrt (p * (p - a) * (p - b) * (p - c))
Слова let и in – ключевые. Выгодным отличием let-выражений является то, что они являются обычными
выражениями и не привязаны к определённому месту как where-выражения. Они могут участвовать в любой
части обычного выражения:
square a b c = let p = (a + b + c) / 2
in
sqrt ((let pa = p - a in p * pa) *
(let pb = p - b
pc = p - c
in
pb * pc))
В этом проявляется их принадлежность композиционному стилю. let-выражения могут участвовать в
любом подвыражении, они также группируются скобками. А where-выражения привязаны к уравнениям в
определении функции.
Также как и в where-выражениях, в let-выражениях слева от знака равно можно проводить декомпозицию
значений.
pred :: Nat -> Nat
pred x = let (Succ y) = x
in
y
Определим функцию фильтрации списков через let:
filter :: (a -> Bool) -> [a] -> [a]
filter
p
[]
= []
filter
p
(x:xs) =
let rest = filter p xs
in
if p x then x : rest else rest
4.2 Декомпозиция
Декомпозиция или сопоставление с образцом позволяет выделять из составных значений, простейшие
значения с помощью которых они были построены
pred (Succ x) = x