\paragraph{Naming Instruments and Tables} In CSound, each table and instrument has a unique identifying integer associated with it. Haskore, on the other hand, uses strings to name instruments. What we need is a way to convert Haskore instrument names to identifier integers that CSound can use. Similar to Haskore's player maps, we define a notion of a \keyword{CSound name map} for this purpose. \begin{haskelllisting}

    > module Haskore.Interface.CSound.InstrumentMap where
    >
    > import Haskore.Interface.CSound (PField, Instrument, instruments)
    >
    > import qualified Data.List as List

    > type SoundTable instr = [(instr, Instrument)]

\end{haskelllisting} A name map can be provided directly in the form \code{[("name1", int1), ("name2", int2), ...]}, or the programmer can define auxiliary functions to make map construction easier. For example: \begin{haskelllisting}

    > tableFromInstruments :: [instr] -> SoundTable instr
    > tableFromInstruments nms = zip nms $ instruments

\end{haskelllisting} The following function will add a name to an existing name map. If the name is already in the map, an error results. \begin{haskelllisting}

    > addToTable :: (Eq instr) =>
    >    instr -> Instrument -> SoundTable instr -> SoundTable instr
    > addToTable nm i instrMap =
    >    if elem nm (map fst instrMap)
    >      then ((nm,i) : instrMap)
    >      else (error ("CSound.addToTable: instrument already in the map"))

\end{haskelllisting} Note the use of the function \function{lookup} imported from \module{List}. \begin{haskelllisting}

    > type ToSound instr = instr -> ([PField], Instrument)

    > lookup :: (Eq instr) => SoundTable instr -> ToSound instr
    > lookup table instr =
    >    maybe (error "CSound.InstrMap.lookup: instrument not found")
    >          ((,) [])
    >          (List.lookup instr table)

\end{haskelllisting}