% from AutoTrack by Stefan Ratschan \subsubsection{Scales} \begin{haskelllisting}
> module Haskore.Basic.Scale
>          (T, ionian, dorian, phrygian, lydian, mixolydian,
>              aeolian, lokrian, altered, htwt, wtht,
>              ionianRel, dorianRel, phrygianRel, lydianRel, mixolydianRel,
>              aeolianRel, lokrianRel, alteredRel, htwtRel, wthtRel,
>
>              fromOffsets, fromIntervals, continue) where
> import qualified Haskore.Basic.Pitch as Pitch
> import Control.Monad(liftM2)
\end{haskelllisting} Some of the following code is taken from the EasyScale implementation of Martin Schwenke. \begin{haskelllisting}
> type T = [Pitch.Absolute]
> type Intervals = [Pitch.Relative]
\end{haskelllisting} Make a scale given a list of absolute pitches, usually starting at 0, and a \type{Pitch.Class} representing the root note of the scale. \begin{haskelllisting}
> fromOffsets :: [Pitch.Absolute] -> Pitch.Class -> T
> fromOffsets ns pc
>   = map (+ Pitch.classToInt pc) ns
\end{haskelllisting} Create a scale from a list of intervals between successive notes. \begin{haskelllisting}
> fromIntervals :: Intervals -> Pitch.Class -> T
> fromIntervals = fromOffsets . scanl (+) 0
\end{haskelllisting} Continue a scale to all octaves. \begin{haskelllisting}
> continue :: T -> T
> continue = liftM2 (+) (iterate (12+) 0)
\end{haskelllisting} Now some general useful scales from music theory. \begin{haskelllisting}
> ionianRel, dorianRel, phrygianRel, lydianRel, mixolydianRel,
>   aeolianRel, lokrianRel, alteredRel, htwtRel,
>   wthtRel :: Intervals
> ionianRel     = [ 2, 2, 1, 2, 2, 2, 1 ]
> dorianRel     = [ 2, 1, 2, 2, 2, 1, 2 ]
> phrygianRel   = [ 1, 2, 2, 2, 1, 2, 2 ]
> lydianRel     = [ 2, 2, 2, 1, 2, 2, 1 ]
> mixolydianRel = [ 2, 2, 1, 2, 2, 1, 2 ]
> aeolianRel    = [ 2, 1, 2, 2, 1, 2, 2 ]
> lokrianRel    = [ 1, 2, 2, 1, 2, 2, 2 ]
> alteredRel    = [ 1, 2, 1, 2, 2, 2, 2 ]
> htwtRel       = [ 1, 2, 1, 2, 1, 2, 1, 2 ]
> wthtRel       = [ 2, 1, 2, 1, 2, 1, 2, 1 ]
> ionian, dorian, phrygian, lydian, mixolydian,
>   aeolian, lokrian, altered, htwt,
>   wtht :: Pitch.Class -> T
> ionian     = fromIntervals ionianRel
> dorian     = fromIntervals dorianRel
> phrygian   = fromIntervals phrygianRel
> lydian     = fromIntervals lydianRel
> mixolydian = fromIntervals mixolydianRel
> aeolian    = fromIntervals aeolianRel
> lokrian    = fromIntervals lokrianRel
> altered    = fromIntervals alteredRel
> htwt       = fromIntervals htwtRel
> wtht       = fromIntervals wthtRel
\end{haskelllisting} Example: Alternatively to applying \function{continue} to a scale you can create an infinitely increasing scale using the definition by intervals, e.g. \code{fromIntervals (cycle ionianRel) Pitch.C}.