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

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

hallCapacity n =

if (n < 10)

then Little

else (if n < 30

then Enough

else Many)

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

all p []

= True

all p (x:xs) = if (p x) then all p xs else False

4.4 Определение функций

Под функцией мы понимаем составной синоним, который принимает аргументы, возможно разбирает их

на части и составляет из этих частей новые выражения. Теперь посмотрим как такие синонимы определяются

в каждом из стилей.

Уравнения

В декларативном стиле функции определяются с помощью уравнений. Пока мы видели лишь этот способ

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

определяется набором уравнений вида:

name декомпозиция1 = композиция1

name декомпозиция2 = композиция2

...

name декомпозицияN = композицияN

Где name – имя функции. В декомпозиции происходит разбор поступающих на вход значений, а в компо-

зиции происходит составление значения результата. Уравнения обходятся вычислителем сверху вниз до тех

пор пока он не найдёт такое уравнение, для которого переданные в функции значения не подойдут в указан-

ный в декомпозиции шаблон значений (если сопоставление с образцом аргументов пройдёт успешно). Как

только такое уравнение найдено, составляется выражение справа от знака равно (композиция). Это значение

будет результатом функции. Если такое уравнение не будет найдено программа остановится с ошибкой.

К примеру попробуйте вычислить в интерпретаторе выражение notT False, для такой функции:

64 | Глава 4: Декларативный и композиционный стиль

notT :: Bool -> Bool

notT True = False

Что мы увидим?

Prelude> notT False

*** Exception: < interactive>:1:4-20: Non-exhaustive patterns in function notT

Интерпретатор сообщил нам о том, что он не нашёл уравнения для переданного в функцию значения.

Безымянные функции

В композиционном стиле функции определяются по-другому. Это необычный метод, он пришёл в

Haskell из лямбда-исчисления. Функции строятся с помощью специальных конструкций, которые называ-

ются лямбда-функциями. По сути лямбда-функции являются безымянными функциями. Давайте посмотрим

на лямбда функцию, которая прибавляет к аргументу единицу:

\x -> x + 1

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

noName, а стрелку на знак равно:

noName x = x + 1

Мы получили обычную функцию Haskell, с такими мы уже много раз встречались. Зачем специальный

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

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

шаблон поведения и затем ссылаться на него по имени функции.

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

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

“на лету”. Предположим, что мы хотим профильтровать список чисел, мы хотим выбрать из них лишь те, что

меньше 10, но больше 2, и к тому же они должны быть чётными. Мы можем написать:

f :: [Int] -> [Int]

f = filter p

where p x = x > 2 && x < 10 && even x

При этом нам приходится давать какое-нибудь имя предикату, например p. С помощью безымянной функ-

ции мы могли бы написать так:

f :: [Int] -> [Int]

f = filter (\x -> x > 2 && x < 10 && even x)

Смотрите мы составили предикат сразу в аргументе функции filter. Выражение (\x -> x > 2 && x <

10 && even x) является обычным значением.

Возможно у вас появился вопрос, где аргумент функции? Где тот список по которому мы проводим филь-

трацию. Ответ на этот вопрос кроется в частичном применении. Давайте вычислим по правилу применения

тип функции filter:

f :: (a -> Bool) -> [a] -> [a],

x :: (Int -> Bool)

------------------------------------------------------

(f x) :: [Int] -> [Int]

После применения параметр a связывается с типом Int, поскольку при применении происходит сопостав-

ление более общего предиката a -> Bool из функции filter с тем, который мы передали первым аргументом

Int -> Bool. После этого мы получаем тип (f x) :: [Int] -> [Int] это как раз тип функции, которая прини-

мает список целых чисел и возвращает список целых чисел. Частичное применение позволяет нам не писать

в таких выражениях:

f xs = filter p xs

where p x = ...

последний аргумент xs.

К примеру вместо

Определение функций | 65

add a b = (+) a b

мы можем просто написать:

add = (+)

Такой стиль определения функций называют бесточечным (point-free).

Давайте выразим функцию filter с помощью лямбда-функций:

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

filter = \p -> \xs -> case xs of

[]

-> []

(x:xs) -> let rest = filter p xs

in

if

p x

then x : rest

else rest

Мы определили функцию filter пользуясь только элементами композиционного стиля. Обратите внима-

ние на скобки в объявлении типа функции. Я хотел напомнить вам о том, что все функции в Haskell являются

функциями одного аргумента. Это определение функции filter как нельзя лучше подчёркивает этот факт.

Мы говорим, что функция filter является функцией одного аргумента p в выражении \p -> , которая возвра-

щает также функцию одного аргумента. Мы выписываем это в явном виде в выражении \xs ->


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

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


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

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


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

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


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

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


фгос  ответы

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


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

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