52700.fb2
initWorld :: IO World
initWorld = do
dirty
<- initDirty
(sense, events) <- percept dirty
return $ World (initPure sense events) dirty
-- в Dirty.hs
initDirty :: IO Dirty
-- в 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. За ответом обратимся к
истории.
Нотная запись в европейской традиции
В европейской традиции принято описывать музыку в виде нотной записи. Нотный лист состоит из серии
нотных станов. Нотный стан состоит из пяти линеек. Каждая линейка обозначает определённую высоту. Нота
состоит из обозначения длительности и высоты. Разные длительности обозначаются штрихами и цветом
ноты, а высоте соответствует расположение на нотном стане.