52700.fb2
некоторое содержание.
data Event t a = Event {
eventStart
:: t,
eventDur
:: t,
eventContent
:: a
} deriving (Show, Eq)
Параметр t символизирует время, а параметр a – некоторое содержание события. Мы будем говорить,
что в некоторый момент времени произошло значение типа a и оно длилось некоторое время. Треком мы
будем называть набор событий, которые длятся определённой время:
data Track t a = Track {
trackDur
:: t,
trackEvents
:: [Event t a]
}
Первый параметр указывает на общую длительность трека, а второй содержит события, которые про-
изошли. Мы явно указываем длительность трека для того, чтобы иметь возможность представить тишину.
Значение тишины будет выглядеть так:
silence t = Track t []
Этим мы говорим, что ничего не произошло в течение t единиц времени.
Музыкальная запись в виде событий | 307
Преобразование событий во времени
Наши события привязаны ко времени. Мы можем ввести линейные операции, которые будут изменять
расположение событий во времени. Самый простой способ изменения положения это задержка. Мы можем
задержать появление события, прибавив какое-нибудь число ко времени начала события:
delayEvent :: Num t => t -> Event t a -> Event t a
delayEvent d e = e{ eventStart = d + eventStart e }
Ещё одно простое преобразование заключается в изменении масштаба времени, в музыке или анимации
этой операции соответствует перемотка. Событие начинает происходить быстрее или медленнее:
stretchEvent :: Num t => t -> Event t a -> Event t a
stretchEvent s e = e{
eventStart
= s * eventStart e,
eventDur
= s * eventDur
e }
Для изменения масштаба времени мы умножили временные параметры на число s. Эти операции мы
можем перенести и на значения типа Track.
delayTrack :: Num t => t -> Track t a -> Track t a
delayTrack d (Track t es) = Track (t + d) (map (delayEvent d) es)
stretchTrack :: Num t => t -> Track t a -> Track t a
stretchTrack s (Track t es) = Track (t * s) (map (stretchEvent s) es)
Класс преобразований во времени
У нас есть аналогичные операции преобразования во времени для событий и треков, это говорит о том,
что мы можем ввести специальный класс, который объединит в себе эти операции. Назовём его классом
Temporal (временн ой):