Мы очень часто пользуемся операцией delay через операцию line. Так в выражении:
q =line [s1, s2, line [loop 2 s3, s4], s5]
Мы будем несколько раз обходить элемент s3 для каждого применения line. К примеру сначала мы
смести все элементы на 3, потом сместим на 5, потом на 10, но вместо этого мы могли бы сразу сместить
все элементы на 18 за один проход. Для этого мы можем закодировать преобразования событий во времени
в типе Track:
data Trackt a = Track{
trackDur
::t,
trackEvents :: TListt a
data TListt a = Empty | Singlea | Append( TListt a) ( TListt a)
| TFun( Tfmt) ( TListt a)
data Tfmt = Tfm !t !t
Тип TListпозволяет проводить быстрое объединение списков. Дополнительный конструктор TFunобо-
значает линейное преобразование списка во времени. Линейное преобразование кодируется двумя числами,
это масштаб и смещение. Мы считаем, что события в конструкторе Singleначинаются в момент времени 0
и длятся 1 единицу времени. Так например событие, которое произошло на 2 единице времени и длилось 4
единицы можно представить так:
TFun(4 2) ( Singlea)
Значение Tfmk d обозначает линейную функцию
f ( x ) = kx + d
Для того чтобы получить настоящие отсчёты по времени мы применяем её к временным координатам
“не преобразованного” события, то есть события Event0 1 a.
Единственное, что нам нужно для того чтобы встроить этот вариант в библиотеку это написать функцию:
fromTList :: TListt a ->[ Eventt a]
И конечно переопределить все функции композиции. Но все сложные функции, которые отвечают за
перевод из Trackв Midiостанутся прежними.
21.7 Краткое содержание
В этой главе мы построили секвенсор для создания midi-файлов. Мы воспользовались библиотекой
HCodecsи создали над ней небольшую надстройку.
В нашей библиотеке примитивными конструкциями были события, параллельная композиция (одновре-
менное воспроизведение) и преобразование событий во времени (сдвиг и масштабирование). Все остальные
операции выражались через эти простейшие операции. Отметим, что есть и другие подходы. Например в биб-
лиотеках Haskoreи Euterpeaпримитивными конструкциями является единичное событие (без отметок во
времени) и параллельная и последовательная композиции. Подход, который мы рассмотрели в более общем
виде реализован в библиотеках temporal -music -notation и temporal -music -notation -demo.
316 | Глава 21: Музыкальный пример
21.8 Упражнения
• Попробуйте написать какую-нибудь мелодию.
• Подумайте каких операций не хватает. Например было бы удобно иметь возможность вырезать из ме-
лодии куски. Так в примере у нас остались хвосты от ударной секции, определите операцию, которая
позволяет убрать лишнее.
Упражнения | 317
Приложения
318 | Приложения
Начало работы с Haskell
Компилятор
Для программирования в Haskell нам понадобится компилятор. Мы будем пользоваться наиболее разви-
тым компилятором~– GHC. Лучше всего устанавливать его вместе с Haskell Platform:
http://hackage.haskell.org/platform/
Haskell Platform содержит стабильную версию компилятора и много хороших, проверенных временем
библиотек. Если по каким-то причинам установить Haskell Platform не удалось. Не отчаивайтесь, можно
загрузить компилятор с сайта GHC:
http://www.haskell.org/ghc/
И далее установить все необходимые библиотеки с Hackage с помощью cabal (устанавливается отдельно
с http://www.haskell.org/cabal/).
Среда разработки
Для Haskell существует очень мало сред разработки. Обычно на Haskell программируют в каких-нибудь
продвинутых текстовых редакторах (vim, Emacs, scite, kate, notepad++). Отметим всё же среду разработки
Leksah (http://leksah.org/), она написана на Haskell и её можно установить с Hackage.
Если вы не хотите разбираться с новым текстовым редактором или средой разработки, и вам нужна лишь
подсветка синтаксиса можно воспользоваться gedit. Пишем код в gedit, сохраняем, переключаемся на ghci,
пробуем, обновляем, пробуем, при случае компилируем или собираем в пакет. Всё это можно делать и в
gedit.
Начало работы с Haskell | 319
Литература
О Haskell написано много интересных книг и статей, но все они на английском. На русском языке выходит
электронный журнал “Практика функционального программирования” (). Пока в нём доминируют два языка
Читать дальше