Изучай Haskell во имя добра! (Липовача) - страница 36

и >badGreeting, например:

>badGreeting :: String

>badGreeting = "О, чёрт, это ты,"


>niceGreeting :: String

>niceGreeting = "Привет! Так приятно тебя увидеть,"


>greet :: String -> String

>greet "Хуан" = niceGreeting ++ " Хуан!"

>greet "Фернандо" = niceGreeting ++ " Фернандо!"

>greet name = badGreeting ++ " " ++ name

Сопоставление с образцами в секции where

Можно использовать привязки в секции >where и для сопоставления с образцом. Перепишем секцию >where в нашей функции так:

>  ...

>  where bmi = weight / height 2

>        (skinny, normal, fat) = (18.5, 25.0, 30.0)

Давайте создадим ещё одну простую функцию, которая принимает два аргумента: имя и фамилию, и возвращает инициалы.

>initials :: String –> String –> String

>initials firstname lastname = [f] ++ ". " ++ [l] ++ "."

>  where (f:_) = firstname

>        (l:_) = lastname

Можно было бы выполнять сопоставление с образцом прямо в параметрах функции (это проще и понятнее), но мы хотим показать, что это допускается сделать и в определениях после ключевого слова >where.

Функции в блоке where

Точно так же, как мы определяли константы в секции >where, можно определять и функции. Придерживаясь нашей темы «здорового» программирования, создадим функцию, которая принимает список из пар «вес–рост» и возвращает список из ИМТ.

>calcBmis :: [(Double, Double)] –> [Double]

>calcBmis xs = [bmi w h | (w, h) <– xs]

>  where bmi weight height = weight / height    2

Видите, что происходит? Причина, по которой нам пришлось представить >bmi в виде функции в данном примере, заключается в том, что мы не можем просто вычислить один ИМТ для параметров, переданных в функцию. Нам необходимо пройтись по всему списку и для каждой пары вычислить ИМТ.

Пусть будет let


Определения, заданные с помощью ключевого слова >let, очень похожи на определения в секциях >where. Ключевое слово >where – это синтаксическая конструкция, которая позволяет вам связывать выражения с переменными в конце функции; объявленные переменные видны во всём теле функции, включая сторожевые условия. Ключевое же слово >let позволяет связывать выражения с именами в любом месте функции; конструкции >let сами по себе являются выражениями, но их область видимости ограничена локальным контекстом. Таким образом, определение >let, сделанное в охранном выражении, видно только в нём самом.

Как и любые другие конструкции языка Haskell, которые используются для привязывания имён к значениям, определения >let могут быть использованы в сопоставлении с образцом. Посмотрим на них в действии! Вот как мы могли бы определить функцию, которая вычисляет площадь поверхности цилиндра по высоте и радиусу: