\subsection{MML} \begin{haskelllisting}

    > module Haskore.Interface.MML where

    > import qualified Haskore.Basic.Pitch    as Pitch
    > import qualified Haskore.Music          as Music
    > import qualified Haskore.Melody         as Melody
    > import           Haskore.Basic.Duration((%+))

    > import Control.Monad.Trans.State (State, state, evalState, )

\end{haskelllisting} I found some music notated in a language called MML. The description consists of strings. \begin{itemize} \item \code{l}$n$ determines the duration of subsequent notes: \code{l1} - whole note, \code{l2} - half note, \code{l4} - quarter note and so on. \item \code{>} switch to the octave above \item \code{<} switch to the octave below \item Lower case letter \code{a} - \code{g} play the note of the corresponding pitch class. \item \code{\#} (sharp) or \code{-} (flat) may follow a note name in order to increase or decrease, respectively, the pitch of the note by a semitone. \item An additional figure for the note duration may follow. \item \code{p} is pause. \end{itemize} See \module{Kantate147} for an example. %\url{http://www.student.oulu.fi/~vtatila/history_of_game_music.html} \begin{haskelllisting}

    > type Accum = (Music.Dur, Pitch.Octave)

    > barToMusic :: String -> Accum -> ([Melody.T ()], Accum)
    > barToMusic []     accum      = ([], accum)
    > barToMusic (c:cs) (dur, oct) =
    >    let charToDur dc = 1 %+ read (dc:[])
    >        prependAtom atom adur (ms, newAccum) =
    >           (atom adur : ms, newAccum)
    >        procNote ndur pitch c0s =
    >           let mkNote c1s = prependAtom (flip (Melody.note (oct, pitch)) ())
    >                                        ndur (barToMusic c1s (dur, oct))
    >           in  case c0s of
    >                 '#':c1s -> procNote ndur (succ pitch) c1s
    >                 '-':c1s -> procNote ndur (pred pitch) c1s
    >                 c1 :c1s -> if '0'<=c1 && c1<='9'
    >                            then procNote (charToDur c1) pitch c1s
    >                            else mkNote c0s
    >                 []      -> mkNote c0s
    >    in  case c of
    >          'c' -> procNote dur Pitch.C cs
    >          'd' -> procNote dur Pitch.D cs
    >          'e' -> procNote dur Pitch.E cs
    >          'f' -> procNote dur Pitch.F cs
    >          'g' -> procNote dur Pitch.G cs
    >          'a' -> procNote dur Pitch.A cs
    >          'b' -> procNote dur Pitch.B cs
    >          'p' -> let (c1:c1s) = cs
    >                 in  prependAtom Music.rest (charToDur c1)
    >                                 (barToMusic c1s (dur, oct))
    >          '<' -> barToMusic cs (dur, oct-1)
    >          '>' -> barToMusic cs (dur, oct+1)
    >          'l' -> let (c1:c1s) = cs
    >                 in  barToMusic c1s (charToDur c1, oct)
    >          _   -> error ("unexpected character '"++[c]++"' in Haskore.Interface.MML description")

    > toMusicState :: String -> State Accum [Melody.T ()]
    > toMusicState s = state (barToMusic s)

    > toMusic :: Pitch.Octave -> String -> Melody.T ()
    > toMusic oct s = Music.line (evalState (toMusicState s) (0, oct))

\end{haskelllisting}