Учебник по Haskell - [35]
выполняет ту же операцию, но на списке списков.
Функция zip принимает два списка и смешивает их в список пар. Как только один из списков оборвётся
оборвётся и список-результат. Эта функция является частным случаем более общей функции zipWith, кото-
рая принимает функцию двух аргументов и два списка и составляет новый список попарных применений.
-- zip-ы
zip :: [a] -> [b] -> [(a, b)]
zip = zipWith (,)
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith z (a:as) (b:bs) =
z a b : zipWith z as bs
zipWith _ _ _
=
[]
Посмотрим как работают эти функции в интерпретаторе:
Prelude> zip [1,2,3] ”hello”
[(1,’h’),(2,’e’),(3,’l’)]
Prelude> zipWith (+) [1,2,3] [3,2,1]
[4,4,4]
Prelude> zipWith (*) [1,2,3] [5,4,3,2,1]
[5,8,9]
Отметим, что в Prelude также определена обратная функция unzip:
68 | Глава 4: Декларативный и композиционный стиль
unzip
:: [(a,b)] -> ([a], [b])
Она берёт список пар и разбивает его на два списка.
Пока по этим определениям кажется, что композиционный стиль совсем нигде не применяется. Он встре-
тился нам лишь в функции break. Но давайте посмотрим и на функции с композиционным стилем:
lines
:: String -> [String]
lines ””
=
[]
lines s
=
let (l, s’) = break (== ’\n’) s
in
l : case s’ of
[]
-> []
(_:s’’) -> lines s’’
Функция line разбивает строку на список строк. Эти строки были разделены в исходной строке символом
переноса ’\n’.
Функция break принимает предикат и список и возвращает два списка. В первом все элементы от начала
списка, которые не удовлетворяют предикату, а во втором все остальные. Наш предикат (== ’\n’) выделяет
все символы кроме переноса каретки. В строке
let (l, s’) = break (== ’\n’) s
Мы сохраняем все символы до ’\n’ от начала строки в переменной l. Затем мы рекурсивно вызываем
функцию lines на оставшейся части списка:
in
l : case s’ of
[]
-> []
(_:s’’) -> lines s’’
При этом мы пропускаем в s’ первый элемент, поскольку он содержит символ переноса каретки.
Посмотрим на ещё одну функцию для работы со строками.
words
:: String -> [String]
words s
=
case dropWhile Char. isSpace s of
”” -> []
s’ -> w : words s’’
where (w, s’’) = break Char. isSpace s’
Функция words делает тоже самое, что и lines, только теперь в качестве разделителя выступает пробел.
Функция dropWhile отбрасывает от начала списка все элементы, которые удовлетворяют предикату. В строке
case dropWhile Char. isSpace s of
Мы одновременно отбрасываем все первые пробелы и готовим значение для декомпозиции. Дальше мы
рассматриваем два возможных случая для строк.
”” -> []
s’ -> w : words s’’
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
В книге кратко изложены ответы на основные вопросы темы «Уголовное право. Особенная часть». Издание поможет систематизировать знания, полученные на лекциях и семинарах, подготовиться к сдаче экзамена или зачета.Пособие адресовано студентам высших и средних образовательных учреждений, а также всем интересующимся данной тематикой.
В книге кратко изложены ответы на основные вопросы темы «Уголовно-исполнительное право». Издание поможет систематизировать знания, полученные на лекциях и семинарах, подготовиться к сдаче экзамена или зачета.Пособие адресовано студентам высших и средних образовательных учреждений, а также всем интересующимся данной тематикой.
Книга посвящена возможностям самого популярного средства цифрового видеомонтажа – Adobe Premiere 6.5. Описываются основные приемы работы с программой, приводятся сведения об управлении проектами и клипами, обсуждаются методы монтажа видео и звука, техника создания титров и добавления спецэффектов, а также освещается процесс окончательного монтирования фильма. На примерах рассматриваются все этапы создания и обработки фильмов для телевидения, видео и мультимедиа.Для широкого круга пользователей.
В учебном пособии в краткой и доступной форме рассмотрены все основные вопросы, предусмотренные государственным образовательным стандартом и учебной программой по дисциплине «Финансовое право».Книга позволит быстро получить основные знания по предмету, а также качественно подготовиться к зачету и экзамену.Рекомендуется студентам, аспирантам и преподавателям по юридическим, экономическим и управленческим специальностям, а также сотрудникам банков.Автор книги, Шевчук Денис Александрович, имеет опыт преподавания различных дисциплин в ведущих ВУЗах Москвы (экономические, юридические, технические, гуманитарные), два высших образования (экономическое и юридическое), более 30 публикаций (статьи и книги), Член Союза Юристов Москвы, Член Союза Журналистов России, Член Союза Журналистов Москвы, Стипендиат Правительства РФ, опыт работы в банках, коммерческих и государственных структурах (в т.ч.
Содержащиеся в пособии контрольно-измерительные материалы (КИМы) для 5 класса, аналогичные материалам ЕГЭ, составлены в соответствии с программой общеобразовательных учреждений по русскому языку и учитывают возрастные особенности учащихся. В конце пособия даны ответы на все варианты тестов, предложены диктанты различных типов.Пособие адресовано учителям, ученикам, их родителям и всем, кому необходимо закрепить и систематизировать знания перед ЕГЭ.
Цель предлагаемого пособия – систематизировать и обогатить представления о природе, структуре и особенностях художественной литературы как вида искусства, помочь совершенствованию читательского мастерства. Книга снабжена кратким словарем основных литературоведческих понятий и терминов (составлен при участии доцента О.В. Быстровой).Для студентов филологических факультетов, учителей, преподавателей литературы высших и средних учебных заведений.