\begin{haskelllisting}
> module Haskore.Melody where
> import Haskore.Basic.Pitch hiding (T)
> import qualified Haskore.Basic.Pitch    as Pitch
> import qualified Haskore.Basic.Duration as Duration
> import qualified Haskore.Music as Music
> import Data.Tuple.HT (mapSnd, )
> import qualified Medium
> import qualified Data.List as List
> import           Data.Maybe(fromMaybe)
> import qualified Data.Accessor.Basic      as Accessor
> data Note attr = Note {noteAttrs_ :: attr, notePitch_ :: Pitch.T}
>     deriving (Show, Eq, Ord)
> type T attr = Music.T (Note attr)
> noteAttrs :: Accessor.T (Note attr) attr
> noteAttrs =
>    Accessor.fromSetGet (\x n -> n{noteAttrs_ = x}) noteAttrs_
>
> notePitch :: Accessor.T (Note attr) Pitch.T
> notePitch =
>    Accessor.fromSetGet (\x n -> n{notePitch_ = x}) notePitch_
> toMelodyNullAttr :: T attr -> T ()
> toMelodyNullAttr =
>    Music.mapNote (\(Note _ p) -> Note () p)
\end{haskelllisting} For convenience, let's create simple names for familiar notes (\figref{note-names}), durations, and rests (\figref{durations-rests}). Despite the large number of them, these names are sufficiently ``unusual'' that name clashes are unlikely. \begin{figure}{\small \begin{haskelllisting}
> note :: Pitch.T -> Duration.T -> attr -> T attr
> note p d' nas = Medium.prim (Music.Atom d' (Just (Note nas p)))
>
> note' :: Pitch.Class -> Pitch.Octave ->
>            Duration.T -> attr -> T attr
> note' = flip (curry note)
>
> cf,c,cs,df,d,ds,ef,e,es,ff,f,fs,gf,g,gs,af,a,as,bf,b,bs ::
>    Pitch.Octave -> Duration.T -> attr -> T attr
>
> cf = note' Cf;  c = note' C;  cs = note' Cs
> df = note' Df;  d = note' D;  ds = note' Ds
> ef = note' Ef;  e = note' E;  es = note' Es
> ff = note' Ff;  f = note' F;  fs = note' Fs
> gf = note' Gf;  g = note' G;  gs = note' Gs
> af = note' Af;  a = note' A;  as = note' As
> bf = note' Bf;  b = note' B;  bs = note' Bs
\end{haskelllisting} } \caption{Convenient note construction functions.} \figlabel{note-names} \end{figure} \begin{comment}
> {-
> o0,  o1, o2, o3, o4, o5, o6, o7, o8, o9,
>  s0, s1, s2, s3, s4, s5, s6, s7, s8, s9 ::
>       (Octave -> Duration.T -> attr -> T note)
>    ->           (Duration.T -> attr -> T note)
> o0 n = n 0; s0 n = n (- 1)
> o1 n = n 1; s1 n = n (- 2)
> o2 n = n 2; s2 n = n (- 3)
> o3 n = n 3; s3 n = n (- 4)
> o4 n = n 4; s4 n = n (- 5)
> o5 n = n 5; s5 n = n (- 6)
> o6 n = n 6; s6 n = n (- 7)
> o7 n = n 7; s7 n = n (- 8)
> o8 n = n 8; s8 n = n (- 9)
> o9 n = n 9; s9 n = n (-10)
> -}
\end{comment} From the notes in the C major triad in register 4, I can now construct a C major arpeggio and chord as well: \begin{haskelllisting}
> cMaj :: [T ()]
> cMaj = map (\n -> n 4 Duration.qn ()) [c,e,g]  -- octave 4, quarter notes
>
> cMajArp, cMajChd :: T ()
> cMajArp = Music.line  cMaj
> cMajChd = Music.chord cMaj
\end{haskelllisting} It is also possible to retrieve the pitch from a melody note. But this should be avoided, since it must be dynamically checked, whether the Melody value actually contains one note. \begin{haskelllisting}
> noteToPitch :: T attr -> Pitch.T
> noteToPitch =
>    let err = error "leastVaryingInversions: melody must consist of a note"
>    in  Accessor.get notePitch .
>           Music.switchList (const (fromMaybe err)) err err err
\end{haskelllisting} \paragraph*{Inversion and Retrograde.} The notions of inversion, retrograde, retrograde inversion, etc. used in 12-tone theory are also easily captured in Haskore. First let's define a transformation from a line created by \code{line} to a list: \begin{haskelllisting}
> invertNote :: Pitch.T -> Note attr -> Note attr
> invertNote r =
>    Accessor.modify notePitch
>       (\ p -> Pitch.fromInt (2 * Pitch.toInt r - Pitch.toInt p))
>
> retro, invert, retroInvert, invertRetro ::
>    [(d, Music.Atom (Note attr))] -> [(d, Music.Atom (Note attr))]
> retro    = List.reverse
> invert l = let r = maybe
>                       (error "invert: first atom must be a note")
>                       (Accessor.get notePitch)
>                       (snd (head l))
>            in  map (mapSnd (fmap (invertNote r))) l
> retroInvert = retro  . invert
> invertRetro = invert . retro
\end{haskelllisting} \begin{exercise} Show that ``\code{retro\ .\ retro}'', ``\code{invert\ .\ invert}'', and ``\code{retroInvert\ .\ invertRetro}'' are the identity on values created by \code{line}. \end{exercise}