Читаем Изучай Haskell во имя добра! полностью

  | weight / height ^ 2 <= 18.5 = "Слышь, эмо, ты дистрофик!"

  | weight / height ^ 2 <= 25.0 = "По части веса ты в норме.

                                   Зато, небось, уродец!"

  | weight / height ^ 2 <= 30.0 = "Ты толстый!

                                   Сбрось хоть немного веса!"

  | otherwise = "Мои поздравления, ты жирный боров!"

Заметили – мы повторили вычисление три раза? Операции копирования и вставки, да ещё повторенные трижды, – сущее наказание для программиста. Раз уж у нас вычисление повторяется три раза, было бы очень удобно, если бы мы могли вычислить его единожды, присвоить результату имя и использовать его, вместо того чтобы повторять вычисление. Можно переписать нашу функцию так:

bmiTell :: Double -> Double -> String bmiTell weight height

  | bmi <= 18.5 = "Слышь, эмо, ты дистрофик!"

  | bmi <= 25.0 = "По части веса ты в норме.

                   Зато, небось, уродец!"

  | bmi <= 30.0 = "Ты толстый!

                   Сбрось хоть немного веса!"

  | otherwise = "Мои поздравления, ты жирный боров!"

  where bmi = weight / height ^ 2

Мы помещаем ключевое слово where после охранных выражений (обычно его печатают с тем же отступом, что и сами охранные выражения), а затем определяем несколько имён или функций. Эти имена видимы внутри объявления функции и позволяют нам не повторять код. Если вдруг нам вздумается вычислять ИМТ другим методом, мы должны исправить способ его вычисления только один раз.

Использование ключевого слова where улучшает читаемость, так как даёт имена понятиям и может сделать программы быстрее за счёт того, что переменные вроде bmi вычисляются лишь однажды. Попробуем зайти ещё дальше и представить нашу функцию так:

bmiTell :: Double -> Double -> String

bmiTell weight height

  | bmi <= skinny = "Слышь, эмо, ты дистрофик!"

  | bmi <= normal = "По части веса ты в норме.

                     Зато, небось, уродец!"

  | bmi <= fat = "Ты толстый!

                  Сбрось хоть немного веса!"

  | otherwise = "Мои поздравления, ты жирный боров!"

  where bmi = weight / height ^ 2

        skinny = 18.5

        normal = 25.0

        fat = 30.0

ПРИМЕЧАНИЕ. Заметьте, что все идентификаторы расположены в одном столбце. Если не отформатировать исходный код подобным образом, язык Haskell не поймёт, что все они – часть одного блока определений.

<p>Область видимости декларации where</p>

Переменные, которые мы определили в секции where нашей функции, видимы только ей самой, так что можно не беспокоиться о том, что мы засоряем пространство имён других функций. Если же нам нужны переменные, доступные в нескольких различных функциях, их следует определить глобально. Привязки в секции where не являются общими для различных образцов данной функции. Предположим, что мы хотим написать функцию, которая принимает на вход имя человека и, если это имя ей знакомо, вежливо его приветствует, а если нет – тоже приветствует, но несколько грубее. Первая попытка может выглядеть примерно так:

greet :: String -> String

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

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

greet name = badGreeting ++ " " ++ name

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

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

Однако эта функция работать не будет, так как имена, введённые в блоке where, видимы только в последнем варианте определения функции. Исправить положение может только глобальное определение функций niceGreeting и badGreeting, например:

badGreeting :: String

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

niceGreeting :: String

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

greet :: String -> String

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

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных