-- в Pure.hs
initPure :: Sense -> [Event] -> Pure
20.6 Детализируем дальше
Вот так на самом интересном месте… Мы вынуждены прерваться. Я надеюсь, что вы уловили основную
идею метода и сможете закончить эту игру самостоятельно. Вся логика игры будет описана в модуле Pure. hs.
Причём в этом модуле будут только чистые функции. Осталось примерно 1000 строк кода. Я не буду выпи-
сывать своё решение, если вы где-то запнётесь или у вас что-то не будет получаться, вы можете свериться с
ним (оно входит в код, что прилагается с книгой).
20.7 Краткое содержание
В этой главе мы посмотрели на две интересные библиотеки. Физический движок Hipmunk и графическую
библиотеку OpenGL и узнали метод укрощения императивного кода. Мы разделили состояние игры на две
части. В одну поместили все те параметры, для которых невозможно обойтись без IO-функций, а в другой
те параметры, которые необходимы для реализации логики игры. Все функции, отвечающие за логику игры
являются чистыми. Параметры императивной части не обновляются сразу, сначала мы делаем с них снимок,
потом передаём этот снимок в чистую часть, и она разбирается с тем как их обновлять. Части общаются между
собой на специальных маленьких языках, которые закодированы в типах. Это язык наблюдений (Event), язык
реакций (Query) и язык отрисовки игрового мира (Picture).
20.8 Упражнения
Закончите код игры. Или, возможно, при знакомстве с Hipmunk у вас появилась идея новой игры с неве-
роятной динамикой. Ещё лучше! Напишите её. При этом продумайте проект игры так, чтобы IO-типы не
разбежались по всей программе.
304 | Глава 20: Императивное программирование
Глава 21
Музыкальный пример
В этой главе мы напишем музыкальный секвенсор. Мы будем переводить нотную запись в midi-файл с
помощью библиотеки HCodecs. Она предоставляет возможность создания midi-файлов по описанию в Haskell.
При этом описание напоминает описание самого формата midi. Мы же хотим подняться уровнем выше и
описывать музыку нотами и композицией нот.
21.1 Музыкальная нотация
Для начала зададимся выясним: а что же такое музыка с точки зрения нашего секвенсора? Мы ищем
представление музыки, термины, в которых было бы удобно мыслить композитору. При этом необходимо
понимать, что наш поиск ограничен средствами низкоуровневого представления музыки. В нашем случае
это midi-файл. Так например мы можем сразу отбросить представление в виде сигналов, последовательности
сэмплов, поскольку мы не сможем реализовать это представление в рамках midi. За ответом обратимся к
истории.
Нотная запись в европейской традиции
В европейской традиции принято описывать музыку в виде нотной записи. Нотный лист состоит из серии
нотных станов. Нотный стан состоит из пяти линеек. Каждая линейка обозначает определённую высоту. Нота
состоит из обозначения длительности и высоты. Разные длительности обозначаются штрихами и цветом
ноты, а высоте соответствует расположение на нотном стане.
Рис. 21.1: Буквенные обозначения высоты ноты
По длительности ноты различают на: целые, половины, четверти, восьмые, шестнадцатые и так далее.
Каждая последующая длительность в два раза меньше предыдущей. Длительность измеряется в долях от
такта. Такты обозначаются сплошной линией, которая перечёркивает все пять линеек нотного стана. По
высоте ноты, зависят от двух целых чисел, это номер октавы и номер ступени лада. В ладе обычно всего 12
ступеней. Их обозначают разными именами. Например в латинской нотации их обозначают так:
0
1
2
3
4
5
6
7
8
9
10
11
C
C
D
D
E
F
F
G
G
A
A
B
C
D
D
E
E
F
G
G
A
A
B
B
do
re
mi
f a
sol
la
ti
В самом нижнем ряду расположены имена нот. Во втором и четвёртом – обозначения нот с диезами и
с бемолями. Одна и та же нота может обозначаться по-разному. Буквами обозначают ноты тональности до
мажор (это семь букв для семи нот), а остальные ноты получают повышением на один шаг с помощью знака