Учебник по Haskell - [31]
square a b c = sqrt (p * (p - a) * (p - b) * (p - c))
where p = (a + b + c) / 2
| 59
Или так:
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
where res = True
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
и организовывать условные вычисления которые зависят от вида поступающих на вход функции значений
not True
= False
not False = True
Сопоставление с образцом
Декомпозицию в декларативном стиле мы уже изучили, это обычный случай разбора значений в аргу-
ментах функции. Рассмотрим одну полезную возможность при декомпозиции. Иногда нам хочется провести
декомпозицию и дать псевдоним всему значению. Это можно сделать с помощью специального символа @.
Например определим функцию, которая возвращает соседние числа для данного числа Пеано:
beside :: Nat -> (Nat, Nat)
beside
Zero
= error ”undefined”
beside
x@(Succ y) = (y, Succ x)
В выражении x“(Succ y)@ мы одновременно проводим разбор и даём имя всему значению.
Декомпозиция | 61
case-выражения
Оказывается декомпозицию можно проводить в любом выражении, для этого существуют case-
выражения:
data AnotherNat = None | One | Two | Many
deriving (Show, Eq)
toAnother :: Nat -> AnotherNat
toAnother x =
case x of
Zero
-> None
Succ Zero
-> One
Succ (Succ Zero)
-> Two
_
-> Many
fromAnother :: AnotherNat -> Nat
fromAnother None
= Zero
fromAnother One
= Succ Zero
fromAnother Two
= Succ (Succ Zero)
fromAnother Many
= error ”undefined”
Слова case и of – ключевые. Выгодным отличием case-выражений является то, что нам не приходит-
ся каждый раз выписывать имя функции. Обратите внимание на то, что в case-выражениях также можно
пользоваться обычными переменными и безымянными переменными.
Для проведения декомпозиции по нескольким переменным можно воспользоваться кортежами. Например
В книге кратко изложены ответы на основные вопросы темы «Уголовное право. Особенная часть». Издание поможет систематизировать знания, полученные на лекциях и семинарах, подготовиться к сдаче экзамена или зачета.Пособие адресовано студентам высших и средних образовательных учреждений, а также всем интересующимся данной тематикой.
В книге кратко изложены ответы на основные вопросы темы «Уголовно-исполнительное право». Издание поможет систематизировать знания, полученные на лекциях и семинарах, подготовиться к сдаче экзамена или зачета.Пособие адресовано студентам высших и средних образовательных учреждений, а также всем интересующимся данной тематикой.
Книга посвящена возможностям самого популярного средства цифрового видеомонтажа – Adobe Premiere 6.5. Описываются основные приемы работы с программой, приводятся сведения об управлении проектами и клипами, обсуждаются методы монтажа видео и звука, техника создания титров и добавления спецэффектов, а также освещается процесс окончательного монтирования фильма. На примерах рассматриваются все этапы создания и обработки фильмов для телевидения, видео и мультимедиа.Для широкого круга пользователей.
В учебном пособии в краткой и доступной форме рассмотрены все основные вопросы, предусмотренные государственным образовательным стандартом и учебной программой по дисциплине «Финансовое право».Книга позволит быстро получить основные знания по предмету, а также качественно подготовиться к зачету и экзамену.Рекомендуется студентам, аспирантам и преподавателям по юридическим, экономическим и управленческим специальностям, а также сотрудникам банков.Автор книги, Шевчук Денис Александрович, имеет опыт преподавания различных дисциплин в ведущих ВУЗах Москвы (экономические, юридические, технические, гуманитарные), два высших образования (экономическое и юридическое), более 30 публикаций (статьи и книги), Член Союза Юристов Москвы, Член Союза Журналистов России, Член Союза Журналистов Москвы, Стипендиат Правительства РФ, опыт работы в банках, коммерческих и государственных структурах (в т.ч.
Содержащиеся в пособии контрольно-измерительные материалы (КИМы) для 5 класса, аналогичные материалам ЕГЭ, составлены в соответствии с программой общеобразовательных учреждений по русскому языку и учитывают возрастные особенности учащихся. В конце пособия даны ответы на все варианты тестов, предложены диктанты различных типов.Пособие адресовано учителям, ученикам, их родителям и всем, кому необходимо закрепить и систематизировать знания перед ЕГЭ.
Цель предлагаемого пособия – систематизировать и обогатить представления о природе, структуре и особенностях художественной литературы как вида искусства, помочь совершенствованию читательского мастерства. Книга снабжена кратким словарем основных литературоведческих понятий и терминов (составлен при участии доцента О.В. Быстровой).Для студентов филологических факультетов, учителей, преподавателей литературы высших и средних учебных заведений.