\subsubsection{Pitch} \seclabel{pitch} Perhaps the most basic musical idea is that of a \keyword{pitch}, which consists of an \keyword{octave} and a \keyword{pitch class} (i.e. one of 12 semi-tones, cf. \secref{discussion:pitch}): \begin{haskelllisting}
> module Haskore.Basic.Pitch where

> import Data.Ix(Ix)

> type T      = (Octave, Class)
> data Class  = Cf | C | Cs | Df | D | Ds | Ef | E | Es | Ff | F | Fs
>             | Gf | G | Gs | Af | A | As | Bf | B | Bs
> type Octave = Int

\end{haskelllisting} So a \type{Pitch.T} is a pair consisting of a pitch class and an octave. Octaves are just integers, but we define a datatype for pitch classes, since distinguishing enharmonics (such as $G^\#$ and $A^b$) may be important (especially for notation). \figref{note-freqs} shows the meaning of the some \type{Pitch.T} values. \begin{figure} \begin{center} \begin{tabular}{llr} $A_2$ & \code{(-3,A)} & 27.5 Hz \\ $A_1$ & \code{(-2,A)} & 55.0 Hz \\ $A$ & \code{(-1,A)} & 110.0 Hz \\ $a$ & \code{( 0,A)} & 220.0 Hz \\ $a^1$ & \code{( 1,A)} & 440.0 Hz \\ $a^2$ & \code{( 2,A)} & 880.0 Hz \end{tabular} \end{center} \caption{Note names, Haskore representations and frequencies.} \figlabel{note-freqs} \end{figure} Treating pitches simply as integers is useful in many settings, so let's also define some functions for converting between \type{Pitch.T} values and \type{Pitch.Absolute} values (integers): \begin{haskelllisting}
> type Absolute = Int
> type Relative = Int
>
> toInt :: T -> Absolute
> toInt (oct,pc) = 12*oct + classToInt pc
>
> fromInt :: Absolute -> T
> fromInt ap =
>    let (oct, n) = divMod ap 12
>    in  (oct, [C,Cs,D,Ds,E,F,Fs,G,Gs,A,As,B] !! n)
>
> classToInt :: Class -> Relative
> classToInt pc = case pc of
>      Cf -> -1;  C ->  0; Cs ->  1   -- or should Cf be 11?
>      Df ->  1;  D ->  2; Ds ->  3
>      Ef ->  3;  E ->  4; Es ->  5
>      Ff ->  4;  F ->  5; Fs ->  6
>      Gf ->  6;  G ->  7; Gs ->  8
>      Af ->  8;  A ->  9; As -> 10
>      Bf -> 10;  B -> 11; Bs -> 12   -- or should Bs be 0?

\end{haskelllisting} Now two functions for parsing and formatting pitch classes in a more human way, that is using '\#' and 'b' suffixes instead of 's' and 'f'. We do not simply use \begin{haskelllisting}
> classParse :: ReadS Class
> classParse (p:'#':r) = reads (p:'s':r)
> classParse (p:'b':r) = reads (p:'f':r)
> classParse r = reads r

> classFormat :: Class -> ShowS
> classFormat pc =
>    let (p:r) = show pc
>    in  (p:) .
>        case r of
>           [] -> id
>           's':[] -> ('#':)
>           'f':[] -> ('b':)
>           _ -> error ("classFormat: Pitch.Class.show must not return suffixes" ++
>                       " other than 's' and 'f'")

\end{haskelllisting} Using \type{Pitch.Absolute} we can compute the frequency associated with a pitch: \begin{haskelllisting}
> intToFreq :: Floating a => Absolute -> a
> intToFreq ap = 440 * 2 ** (fromIntegral (ap - toInt (1,A)) / 12)

\end{haskelllisting} We can also define a function \function{Pitch.transpose}, which transposes pitches (analogous to \function{Music.transpose}, which transposes values of type \type{Music.T}): \begin{haskelllisting}
> transpose :: Relative -> T -> T
> transpose i p = fromInt (toInt p + i)

\end{haskelllisting} \begin{exercise} Show that\ \ \code{toInt\ .\ fromInt = id}, and, up to enharmonic equivalences,\newline \code{fromInt\ .\ toInt = id}. \end{exercise} \begin{exercise} Show that\ \ \code{transpose i (transpose j p) = transpose (i+j) p}. \end{exercise}