Учебник по Haskell - [40]

Шрифт
Интервал

это простые значения. Этот приём используется в Haskell очень активно. Пока нам встретились лишь две

инфиксных операции для функций (это композиция и применение с низким приоритетом), но в будущем вы

столкнётесь с целым морем подобных операций. Все они служат одной цели, они прячут аргументы функции,

позволяя быстро составлять функции на лету из примитивов. Чтобы не захлебнуться в этом море помните,

что скорее всего новый символ означает либо композицию либо применение для функций специального

вида.

Возведём в четвёртую степень:

80 | Глава 5: Функции высшего порядка

*FunNat> map (f . f) [1,2,3,4,5]

[1,16,81,256,625]

Составим функцию двух аргументов, которая будет вычислять сумму квадратов двух аргументов:

*FunNat> let x = const id

*FunNat> let y = flip $ const id

*FunNat> let d = x * x + y * y

*FunNat> d 1 2

5

*FunNat> d 3 2

13

Так мы составили функцию, ни прибегая к помощи аргументов. Эти выражения могут стать частью других

выражений:

*FunNat> filter

((< 10) . d 1) [1,2,3,4,5]

[1,2]

*FunNat> zipWith d [1,2,3] [3,2,1]

[10,8,10]

*FunNat> foldr (x*x - y*y) 0 [1,2,3,4]

3721610024

*FunNat> zipWith ((-) * (-) + const id) [1,2,3] [3,2,1]

[7,2,5]

В последнем выражении трудно предугадать результат. В таких выражениях всё-таки лучше пользоваться

синонимами. В бесточечном стиле мы можем несколькими операциями собрать из базовых функций сложную

функцию и передать её аргументом в другую функцию, которая также может поучаствовать в комбинации

других функций!

5.4 Функции, возвращающие несколько значений

Как было сказано ранее функции, которые возвращают несколько значений, реализованы в Haskell с по-

мощью кортежей. Например функция, которая расщепляет поток на голову и хвост выглядит так:

decons :: Stream a -> (a, Stream a)

decons (a :& as) = (a, as)

Здесь функция возвращает сразу два значения. Но всегда ли уместно пользоваться кортежами? Для ком-

позиции функций, которые возвращают несколько значений нам придётся разбирать возвращаемые значения

с помощью сопоставления с образцом и затем использовать эти значения в других функциях. Посудите сами

если у нас есть функции:

f :: a

-> (b1, b2)

g :: b1 -> (c1, c2)

h :: b2 -> (c3, c4)

Мы уже не сможем комбинировать их так просто как если бы это были обычные функции без кортежей.

q x = (\(a, b) -> (g a, h b)) (f x)

В случае пар нам могут прийти на помощь функции first и second:

q = first g . second h . f

Если мы захотим составить какую-нибудь другую функцию из q, то ситуация заметно усложнится. Функ-

ции, возвращающие кортежи, сложнее комбинировать в бесточечном стиле. Здесь стоит вспомнить правило

Unix.

Пишите функции, которые делают одну вещь, но делают её хорошо.

Функции, возвращающие несколько значений | 81

Функция, которая возвращает кортеж пытается сделать сразу несколько дел. И теряет в гибкости, ей

трудно взаимодействовать с другими функциями. Старайтесь чтобы таких функций было как можно меньше.

Если функция возвращает несколько значений, попытайтесь разбить её на несколько, которые возвраща-

ют лишь одно значение. Часто бывает так, что эти значения тесно связаны между собой и такую функцию

не удаётся разбить на несколько составляющих. Если у вас появляется много таких функций, то это повод

задуматься о создании нового типа данных.

Например в качестве точки на плоскости можно использовать пару (Float, Float). В этом случае, если

вы начнёте писать модуль на геометрическую тему у вас появится много функций, которые принимают и

возвращают точки:

rotate

:: Float -> (Float, Float) -> (Float, Float)

norm

:: (Float, Float) -> (Float, Float)

translate

:: (Float, Float) -> (Float, Float) -> (Float, Float)

...

Все они стараются делать несколько дел одновременно, возвращая кортежи. Но мы можем изменить

ситуацию определением новых типов:

data Point

= Point

Float Float

data Vector = Vector Float Float

data Angle

= Angle

Float

Объявления функций станут более краткими и наглядными.

rotate

:: Angle

-> Point -> Point

norm

:: Point

-> Point

translate

:: Vector -> Point -> Point

...

5.5 Комбинатор неподвижной точки

Познакомимся с функцией fix или комбинатором неподвижной точки. По хорошему об этой функции

следовало бы рассказать в разделе обобщённые функции. Но я пропустил её нарошно, для простоты изло-

жения. В этом разделе градус сложности резко подскакивает, если вы ранее не встречались с этой функцией

она может показаться вам очень необычной. Для начала посмотрим на её тип:

Prelude> :m +Data.Function

Prelude Data.Function> :t fix

fix :: (a -> a) -> a

Странно fix принимает функцию и возвращает значение, обычно всё происходит наоборот. Теперь по-

смотрим на определение:

fix f = let x = f x

in

x

Если вы запутались, то посмыслу это определение равносильно такому:

fix f = f (fix f)

Функция fix берёт функцию и начинает бесконечно нанизывать её саму на себя. Так мы получаем, что-то

вроде:

f (f (f (f (... ))))

Зачем нам такая функция? Помните в самом конце четвёртой главы в упражнениях мы составляли бес-

конечные потоки. Мы делали это так:

data Stream a = a :& Stream a

constStream :: a -> Stream a

constStream a = a :& constStream a

82 | Глава 5: Функции высшего порядка

Если смотреть на функцию constStream очень долго, то рано или поздно в ней проглянет функция fix. Я


Рекомендуем почитать
Уголовное право. Особенная часть

В книге кратко изложены ответы на основные вопросы темы «Уголовное право. Особенная часть». Издание поможет систематизировать знания, полученные на лекциях и семинарах, подготовиться к сдаче экзамена или зачета.Пособие адресовано студентам высших и средних образовательных учреждений, а также всем интересующимся данной тематикой.


Уголовно-исполнительное право

В книге кратко изложены ответы на основные вопросы темы «Уголовно-исполнительное право». Издание поможет систематизировать знания, полученные на лекциях и семинарах, подготовиться к сдаче экзамена или зачета.Пособие адресовано студентам высших и средних образовательных учреждений, а также всем интересующимся данной тематикой.


Самоучитель Adobe Premiere 6.5

Книга посвящена возможностям самого популярного средства цифрового видеомонтажа – Adobe Premiere 6.5. Описываются основные приемы работы с программой, приводятся сведения об управлении проектами и клипами, обсуждаются методы монтажа видео и звука, техника создания титров и добавления спецэффектов, а также освещается процесс окончательного монтирования фильма. На примерах рассматриваются все этапы создания и обработки фильмов для телевидения, видео и мультимедиа.Для широкого круга пользователей.


Финансовое право

В учебном пособии в краткой и доступной форме рассмотрены все основные вопросы, предусмотренные государственным образовательным стандартом и учебной программой по дисциплине «Финансовое право».Книга позволит быстро получить основные знания по предмету, а также качественно подготовиться к зачету и экзамену.Рекомендуется студентам, аспирантам и преподавателям по юридическим, экономическим и управленческим специальностям, а также сотрудникам банков.Автор книги, Шевчук Денис Александрович, имеет опыт преподавания различных дисциплин в ведущих ВУЗах Москвы (экономические, юридические, технические, гуманитарные), два высших образования (экономическое и юридическое), более 30 публикаций (статьи и книги), Член Союза Юристов Москвы, Член Союза Журналистов России, Член Союза Журналистов Москвы, Стипендиат Правительства РФ, опыт работы в банках, коммерческих и государственных структурах (в т.ч.


фгос  ответы

Содержащиеся в пособии контрольно-измерительные материалы (КИМы) для 5 класса, аналогичные материалам ЕГЭ, составлены в соответствии с программой общеобразовательных учреждений по русскому языку и учитывают возрастные особенности учащихся. В конце пособия даны ответы на все варианты тестов, предложены диктанты различных типов.Пособие адресовано учителям, ученикам, их родителям и всем, кому необходимо закрепить и систематизировать знания перед ЕГЭ.


Теория литературы. Чтение как творчество

Цель предлагаемого пособия – систематизировать и обогатить представления о природе, структуре и особенностях художественной литературы как вида искусства, помочь совершенствованию читательского мастерства. Книга снабжена кратким словарем основных литературоведческих понятий и терминов (составлен при участии доцента О.В. Быстровой).Для студентов филологических факультетов, учителей, преподавателей литературы высших и средних учебных заведений.