Читаем Учебник по Haskell полностью

where rest = filter p xs

Или мы можем разместить охранные выражения по-другому:

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

filter

p

[]

= []

filter

p

(x:xs)

| p x

= x : rest

| otherwise = rest

where rest = filter p xs

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

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

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

удовлетворяют ли все элементы списка данному предикату.

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

all p []

= True

all p (x:xs)

| p x

= all p xs

| otherwise = False

С помощью охранных выражений можно очень наглядно описывать условные выражения. Но иногда мож-

но обойтись и простыми логическими операциями. Например функцию all можно было бы определить так:

Условные выражения | 63

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

all

p

[]

= True

all

p

(x:xs)

= p x && all p xs

Или так:

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

all

p

xs = null (filter notP xs)

where notP x = not (p x)

Или даже так:

import Prelude(all)

Функция null определена в Prelude она возвращает True только если список пуст.

if-выражения

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

Вспомним как они выглядят:

a = if bool

then x1

else x2

Слова if, then и else – ключевые. Тип a, x1 и x2 совпадают.

Любое охранное выражение, в котором больше одной альтернативы, можно представить в виде if-

выражения и наоборот. Перепишем все функции их предыдущего подраздела с помощью if-выражений:

hallCapacity :: Int -> HowMany

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

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

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

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

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

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

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

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

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

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