% from AutoTrack by Stefan Ratschan \begin{haskelllisting}
> module Haskore.Interface.AutoTrack.EventChart
>    (T(Cons), events, fromChordChart, fromChartBar) where
> import qualified Haskore.Music        as Music
> import qualified Haskore.Interface.AutoTrack.ChartBar    as ChartBar
> import qualified Haskore.Interface.AutoTrack.ChordChart  as ChordChart
> import qualified Haskore.Interface.AutoTrack.ChordSymbol as ChordSymbol
> import qualified Haskore.Interface.AutoTrack.Transposeable as Transposeable
> import qualified Haskore.Basic.Duration as Dur
> import qualified Data.List as List
> import           Data.Maybe(fromJust)
\end{haskelllisting} Event charts are currently not used. An event chart represents a list of objects of a certain type and duration (the ``events''). \begin{haskelllisting}
> data T e = Cons {events :: [ (Music.Dur, e) ] } deriving Show
> fromChordChart :: ChordChart.T -> T ChordSymbol.T
> fromChordChart (ChordChart.Cons c) =
>    Cons (concatMap (events . fromChartBar) c)
> fromChartBar :: ChartBar.T -> T ChordSymbol.T
> fromChartBar (ChartBar.Cons d l) =
>    let f c = (d / Dur.fromRatio (List.genericLength l), fromJust c)
>    in  Cons (map f l)
\end{haskelllisting} Transpose an event chart by a certain number of semitones \begin{haskelllisting}
> instance (Transposeable.C a) => Transposeable.C (T a) where
>   transpose i = fmap (Transposeable.transpose i)
\end{haskelllisting} Event charts can also act as functors: \begin{haskelllisting}
> instance Functor T where
>   fmap f (Cons v) = Cons (map ( \(d, c) -> (d, f c) ) v)
\end{haskelllisting}