52700.fb2 Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 60

Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 60

Или так:

square a b c = sqrt (p * (p - a) * (p - b) * (p - c)) where

p = (a + b + c) / 2

За определением функции следует специальное слово where, которое вводит локальные имена-

синонимы. При этом аргументы функции включены в область видимости имён. Синонимов может быть

несколько:

square a b c = sqrt (p * pa * pb * pc)

where p

= (a + b + c) / 2

pa = p - a

pb = p - b

pc = p - c

Отметим, что отступы обязательны. Haskell по отступам понимает, что эти выражения относятся к where.

Как и в случае объявления функций порядок следования локальных переменных в where-выражении не

важен. Главное чтобы в выражениях справа от знака равно мы пользовались именами из списка аргументов

исходной функции или другими определёнными именами. Локальные переменные видны только в пределах

той функции, в которой они вводятся.

Что интересно, слева от знака равно в where-выражениях можно проводить декомпозицию значений, так-

же как и в аргументах функции:

pred :: Nat -> Nat

pred x = y

where (Succ y) = x

Эта функция делает тоже самое что и функция

pred :: Nat -> Nat

pred (Succ y) = y

В where-выражениях можно определять новые функции а также выписывать их типы:

add2 x = succ (succ x)

where succ :: Int -> Int

succ x = x + 1

А можно и не выписывать, компилятор догадается:

add2 x = succ (succ x)

where succ x = x + 1

Но иногда это бывает полезно, при использовании классов типов, для избежания неопределённости при-

менения.

Приведём ещё один пример. Посмотрим на функцию фильтрации списков, она определена в Prelude:

filter :: (a -> Bool) -> [a] -> [a]

filter

p

[]

= []

filter

p

(x:xs) = if p x then x : rest else rest

where rest = filter p xs

Мы определили локальную переменную rest, которая указывает на рекурсивный вызов функции на остав-

шейся части списка.

where-выражения определяются для каждого уравнения в определении функции:

even :: Nat -> Bool

even Zero

= res