{-| This module translates Pitch Class Sets to and from /Compact Format/. In Compact Format, data such as StdSet [0,4,7,11] could be represented by the string 047B, which uses a single alphanumeric character for each pitch class element. Limitations: this module is only usable for pitch class sets of modulus 36 or below. Beyond that, it's not really certain that a compact format would be of any practical use. -} module Data.PcSets.Compact ( -- * Constructors: Compact Format to PcSet toGenSet , toStdSet , toStdSet' , toGenRow , toStdRow , toStdRow' -- * Abbreviators: PcSet to Compact Format , compact , compact' ) where\end{code} \subsection{The Module Import List} \begin{code}

import qualified Data.PcSets as P\end{code} \section{Constructors: Compact Format to PcSet} \subsection{Pitch Class Sets} \subsubsection{toGenSet} \begin{code}

{-| Creates a new General Pitch Class Set of modulus /n/. Alphanumeric character values 0-9 and A-Z represent the numbers 0 to 36. Other inputs, including whitespace, are ignored. -} toGenSet :: Int -> String -> P.GenSet toGenSet n = P.genset n . trBase36\end{code} \subsubsection{toStdSet} \begin{code}

{-| Creates a new Standard (modulus 12) Pitch Class Set. Here, input characters 0-9 count as their decimal equivalents; the letter /A/ stands for 10, and the letter /B/ stands for 11. Other inputs, including whitespace, are ignored. -} toStdSet :: String -> P.StdSet toStdSet = P.stdset . trBase36\end{code} \subsubsection{toStdSet'} \begin{code}

{-| Creates a new Standard (modulus 12) Pitch Class Set, using an alternative duodecimal format. Here, input characters 0-9 count as their decimal equivalents; the letter /T/ stands for 10, and the letter /E/ stands for 11. Other inputs, including whitespace, are ignored. -} toStdSet' :: String -> P.StdSet toStdSet' = P.stdset . trBase12\end{code} \subsection{Tone Rows} \subsubsection{toGenRow} \begin{code}

{-| Creates a new General Tone Row of modulus /n/. Alphanumeric character values 0-9 and A-Z represent the numbers 0 to 36. Other inputs, including whitespace, are ignored. Since Tone Rows must contain all possible elements, an incomplete entry list will result in a new row with the missing tones added at the end. -} toGenRow :: Int -> String -> P.GenRow toGenRow n = P.genrow n . trBase36\end{code} \subsubsection{toStdRow} \begin{code}

{-| Creates a new Standard (modulus 12) Tone Row. Here, input characters 0-9 count as their decimal equivalents; the letter /A/ stands for 10, and the letter /B/ stands for 11. Other inputs, including whitespace, are ignored. (Also, see notes for 'toGenRow'.) -} toStdRow :: String -> P.StdRow toStdRow = P.stdrow . trBase36\end{code} \subsubsection{toStdRow'} \begin{code}

{-| Creates a new Standard (modulus 12) Tone Row, using an alternative duodecimal format. Here, input characters 0-9 count as their decimal equivalents; the letter /T/ stands for 10, and the letter /E/ stands for 11. Other inputs, including whitespace, are ignored. (Also, see notes for 'toGenRow'.) -} toStdRow' :: String -> P.StdRow toStdRow' = P.stdrow . trBase12\end{code} \section{Abbreviators: PcSet to Compact Format} \subsection{General Case} \begin{code}

{-| Translates a Pitch Class Set or Tone Row to Compact Format. Values from 0-9 are translated as the characters 0-9; values from 10 to 35 are translated as charaters A-Z. Values which are out of the representable range are ignored, therefore this function is not suitable for sets of modulus 37 or greater. -} compact :: P.PcSet a => a -> String compact = filter (/= '#') . map f . P.elements where f n | 0 <= n && n <= 9 = toEnum (n + 48) | 9 < n && n < 37 = toEnum (n + 55) | otherwise = '#' -- ignore out of range\end{code} \subsection{Specialized Standard} \begin{code}

{-| This function is identical to 'compact', except that Standard (modulus 12) sets and rows are rendered using 'T' for 10 and 'E' for 11. -} compact' :: P.PcSet a => a -> String compact' ps = if P.modulus ps /= 12 then compact ps else filter (/= '#') . map f . P.elements $ ps where f n | 0 <= n && n <= 9 = toEnum (n + 48) | n == 10 = 'T' | n == 11 = 'E' | otherwise = '#' -- ignore out of range\end{code} \section{Not Exported} \subsection{Alphanumeric Translators} \subsubsection{Base 36} \begin{code}

trBase36 :: String -> [Int] trBase36 = filter (>= 0) . map f where f c | '0' <= c && c <= '9' = fromEnum c - 48 | 'A' <= c && c <= 'Z' = fromEnum c - 55 | otherwise = -1 -- ignore nonsense\end{code} \subsubsection{Duodecimal} \begin{code}

trBase12 :: String -> [Int] trBase12 = filter (>= 0) . map f where f c | '0' <= c && c <= '9' = fromEnum c - 48 | c == 'T' = 10 | c == 'E' = 11 | otherwise = -1 -- ignore nonsense\end{code} % last line Data.PcSets.Compact