52700.fb2 Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 337

Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 337

Добавим функцию инициализации игры:

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. За ответом обратимся к

истории.

Нотная запись в европейской традиции

В европейской традиции принято описывать музыку в виде нотной записи. Нотный лист состоит из серии

нотных станов. Нотный стан состоит из пяти линеек. Каждая линейка обозначает определённую высоту. Нота

состоит из обозначения длительности и высоты. Разные длительности обозначаются штрихами и цветом

ноты, а высоте соответствует расположение на нотном стане.