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

where (w, s’’) = break Char. isSpace s’

Если строка пуста, то делать больше нечего. Если – нет, мы также как и в предыдущей функции приме-

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

функцию words на оставшейся части списка.

4.6 Краткое содержание

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

появлялись парами. Сведём их в таблицу:

Элемент

Декларативный стиль

Композиционный

Локальные переменные

where-выражения

let-выражения

Декомпозиция

Сопоставление с образцом

case-выражения

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

Охранные выражения

if-выражения

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

Уравнения

лямбда-функции

Краткое содержание | 69

Особенности синтаксиса

Нам встретилась новая конструкция в сопоставлении с образцом:

beside :: Nat -> (Nat, Nat)

beside

Zero

= error ”undefined”

beside

x@(Succ y) = (y, Succ x)

Она позволяет проводить декомпозицию и давать имя всему значению одновременно. Такие выражения

x(...)@ в англоязычной литературе принято называть as-patterns.

4.7 Упражнения

• В этой главе нам встретилось много полезных стандартных функций, потренируйтесь с ними в интер-

претаторе. Вызывайте их с различными значениями, экспериментируйте.

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

• Посмотрите на те функции, которые мы прошли и попробуйте переписать их определения шиворот

на выворот. Если вы видите, что элемент написан композиционном стиле перепишите его в деклара-

тивном и наоборот. Получившиеся функции могут показаться монстрами, но это упражнение может

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

иного стиля.

• Определите модуль, который будет вычислять площади простых фигур, треугольника, окружности,

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

• Поток это бесконечный список, или список, у которого нет конструктора пустого списка:

data Stream a = a :& Stream a

Так например мы можем составить поток из всех чисел Пеано:

nats :: Nat -> Stream Nat

nats a = a :& nats (Succ a)

Или поток, который содержит один и тот же элемент:

constStream :: a -> Stream a

constStream a = a :& constStream a

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

поскольку мы не сможем распечатать поток целиком (ведь он бесконечный):

-- Первый элемент потока

head :: Stream a -> a

-- Хвост потока, всё кроме первого элемента

tail :: Stream a -> Stream a

-- n-тый элемент потока

(!! ) :: Stream a -> Int -> a

-- Берёт из потока несколько первых элементов:

take :: Int -> Stream a -> [a]

Имена этих функций будут совпадать с именами функций для списков чтобы избежать коллизий имён

мы воспользуемся квалифицированным импортом функций. Делается это так:

import qualified Prelude as P( определения )

Слова qualified и as – ключевые. Теперь для использования функций из модуля Prelude мы будем писать

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

ванными именами только для тех функций, для которых возможна коллизия имён можно поступить так:

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

import qualified Prelude as P

import Prelude

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

Для удобства тестирования можно определить такую функцию печати потоков:

instance Show a => Show (Stream a) where

show xs =

showInfinity (show (take 5 xs))

where showInfinity x = P. init x

P.++ ”...”

Функция P. init выделяет все элементы списка кроме последнего. В данном случае она откусит от строки

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

Функции преобразования потоков:

-- Преобразование потока

map :: (a -> b) -> Stream a -> Stream b

-- Фильтрация потока

filter :: (a -> Bool) -> Stream a -> Stream a

-- zip-ы для потоков:

zip :: Stream a -> Stream b -> Stream (a, b)

zipWith :: (a -> b -> c) -> Stream a -> Stream b -> Stream c

Функция генерации потока:

iterate :: (a -> a) -> a -> Stream a

Эта функция принимает два аргумента: функцию следующего элемента потока и значение первого эле-

мента потока и возвращает поток:

iterate f a = a :& f a :& f (f a) :& f (f (f a)) :& ...

Так с помощью этой функции можно создать поток всех чисел Пеано от нуля или постоянный поток:

nats

= iterate Succ Zero

constStream a

= iterate (\x -> x) a

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

пока мы не будем вдаваться в детали того как это работает, просто попробуйте определить этот модуль и

посмотрите в интерпретаторе, что получится.

Упражнения | 71

Глава 5

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

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

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

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

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

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

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

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

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

Все жанры