%-*- mode: Latex; abbrev-mode: true; auto-fill-function: do-auto-fill -*- %include lhs2TeX.fmt %include myFormat.fmt \chapter{More Music} \label{ch:more-music} \begin{code} module Euterpea.MoreMusic where import Euterpea.Music \end{code} In this chapter we will explore a number of simple musical ideas, and contribute to a growing collection of Haskell functions for expressing those ideas. %% \section{Lines and Chords} %% %% Two common ideas in music are the construction of notes in a %% horizontal fashion (a \emph{line} or \emph{melody}), and in a vertical %% fashion (a \emph{chord}): %% \begin{code} %% line, chord :: [Music a] -> Music a %% line = foldr1 (:+:) %% chord = foldr1 (:=:) %% \end{code} %% From the notes in the C major triad in register 4, I can now construct %% a C major arpeggio and chord as well: %% \begin{code} %% cMaj = [ n 4 qn [] | n <- [c,e,g] ] -- octave 4, quarter notes %% cMajArp = line cMaj %% cMajChd = chord cMaj %% \end{code} \out{ \begin{code} line, chord :: [Music a] -> Music a line = foldr (:+:) (rest 0) chord = foldr (:=:) (rest 0) line1, chord1 :: [Music a] -> Music a line1 = foldr1 (:+:) chord1 = foldr1 (:=:) \end{code} } \section{Delay and Repeat} %% Suppose that we wish to describe a melody |m| accompanied by %% an identical voice a perfect 5th higher. In Euterpea we can simply write %% |m :=: transpose 7 m|. We can delay the start of a music value simply by inserting a rest in front of it, and we can package that in a function like this: where: \begin{code} delay :: Dur -> Music a -> Music a delay d m = rest d :+: m \end{code} With |delay| it is easy to write canon-like structures such as |m :=: delay d m|, a song written in rounds (see Exercise \ref{ex:frere-jacques}), and so on. In Chapter \ref{ch:interlude} we introduced a function to repeat a musical phrase a certain number of times: \begin{code} timesM :: Int -> Music a -> Music a timesM 0 m = rest 0 timesM n m = m :+: timesM (n-1) m \end{code} More interestingly, Haskell's non-strict semantics allows us to define \emph{infinite} musical values. For example, a musical value may be repeated \emph{ad nauseam} using this simple function: \begin{code} repeatM :: Music a -> Music a repeatM m = m :+: repeatM m \end{code} Thus, for example, an infinite ostinato can be expressed in this way, and then used in different contexts that automatically extract only the portion that is actually needed. We will introduce shortly some functions that create such contexts. %% \vspace{.1in}\hrule %% \begin{exercise}{\em %% Define a function |repM :: Int -> Music a -> Music a| such that %% |repM n m| repeats |m| |n| times.} %% \end{exercise} %% \vspace{.1in}\hrule \section{Inversion and Retrograde} The notions of inversion, retrograde, retrograde inversion, etc.\ as used in twelve-tone theory are also easily captured in Euterpea. These terms are usually applied only to ``lines'' of notes, i.e.\ a melody (in twelve-tone theory it is called a ``row''). The \emph{retrograde} of a line is simply its reverse---i.e.\ the notes played in the reverse order. The \emph{inversion} of a line is with respect to a given pitch (by convention usually the first pitch), where the intervals between successive pitches are inverted, i.e.\ negated. If the absolute pitch of the first note is |ap|, then each pitch |p| is converted into an absolute pitch |(ap - absPitch p) + ap|, in other words |2*ap - absPitch p|. To do all this in Haskell, let's first define a transformation from a line created by |line| to a list: \begin{code} lineToList :: Music a -> [Music a] lineToList (Prim (Rest 0)) = [] lineToList (n :+: ns) = n : lineToList ns lineToList _ = error "lineToList: argument not created by function line" \end{code} Using this function it is then straightforward to define |invert|: \begin{code} invert :: Music Pitch -> Music Pitch invert m = let l@(Prim (Note _ r) : _) = lineToList m inv (Prim (Note d p)) = note d (pitch (2 * absPitch r - absPitch p)) inv (Prim (Rest d)) = rest d in line (map inv l) \end{code} %% invert m = line (map inv l) %% where l@(Prim (Note _ r) : _) = lineToList m %% inv (Prim (Note d p)) = %% note d (pitch (2 * absPitch r - absPitch p)) %% inv (Prim (Rest d)) = rest d \syn{The pattern |l@(Prim (Note _ r) : _)| is called an \emph{as pattern}. It behaves just like the pattern |Prim (Note _ r) : _| but additionally binds |l| to the value of a successful match to that pattern. |l| can then be used wherever it is in scope, such as in the last line of the function definition.} With |lineToList| and |invert| it is then easy to define the remaining functions via composition: \begin{code} retro, retroInvert, invertRetro :: Music Pitch -> Music Pitch retro = line . reverse . lineToList retroInvert = retro . invert invertRetro = invert . retro \end{code} \vspace{.1in}\hrule \begin{exercise}{\em Show that |retro . retro|, |invert . invert|, and |retroInvert . invertRetro| are the identity on values created by |line|.} \end{exercise} \vspace{.1in}\hrule \begin{figure*} \centerline{ \epsfysize=2.0in \epsfbox{Pics/pr12.eps} } \caption{Nested Polyrhythms (top: |pr1|; bottom: |pr2|)} \label{polyrhythms} \end{figure*} \section{Polyrhythms} For some rhythmical ideas, first note that if |m| is a line of three eighth notes, then |tempo (3/2) m| is a \emph{triplet} of eighth notes, just as we did in Chapter \ref{ch:interlude}. In fact |tempo| can be used to create quite complex rhythmical patterns. For example, consider the ``nested polyrhythms'' shown in Figure \ref{polyrhythms}. They can be expressed naturally in Euterpea as follows (note the use of a |let| clause in |pr2| to capture recurring phrases): \begin{code} pr1, pr2 :: Pitch -> Music Pitch pr1 p = tempo (5/6) ( tempo (4/3) ( mkLn 1 p qn :+: tempo (3/2) ( mkLn 3 p en :+: mkLn 2 p sn :+: mkLn 1 p qn ) :+: mkLn 1 p qn) :+: tempo (3/2) ( mkLn 6 p en)) pr2 p = let m1 = tempo (5/4) (tempo (3/2) m2 :+: m2) m2 = mkLn 3 p en in tempo (7/6) ( m1 :+: tempo (5/4) (mkLn 5 p en) :+: m1 :+: tempo (3/2) m2) mkLn n p d = line $ take n $ repeat $ note d p \end{code} % $ \syn{|take n lst| is the first |n| elements of the list |lst|. For example: \begin{spec} take 3 [C,Cs,Df,D,Ds] ===> [C,Cs,Df] \end{spec} |repeat x| is the infinite list of the same value |x|. For example: \begin{spec} take 3 (repeat 42) ===> [42,42,42] \end{spec} } To play polyrhythms |pr1| and |pr2| in parallel using middle C and middle G, respectively, we do the following: \begin{code} pr12 :: Music Pitch pr12 = pr1 (C,4) :=: pr2 (G,4) \end{code} \newpage \section{Symbolic Meter Changes} We can implement the notion of ``symbolic meter changes'' of the form ``oldnote = newnote'' (quarter note = dotted eighth, for example) by defining an infix function: \begin{code} (=:=) :: Dur -> Dur -> Music a -> Music a old =:= new = tempo (new/old) \end{code} Of course, using the new function is not much shorter than using |tempo| directly, but it may have mnemonic value. \section{Computing Duration} \label{sec:duration} It is often desirable to compute the \emph{duration}, in whole notes, of a musical value; we can do so as follows: \begin{code} dur :: Music a -> Dur dur (Prim (Note d _)) = d dur (Prim (Rest d)) = d dur (m1 :+: m2) = dur m1 + dur m2 dur (m1 :=: m2) = dur m1 `max` dur m2 dur (Modify (Tempo r) m) = dur m / r dur (Modify _ m) = dur m \end{code} The duration of a primitive value is obvious. The duration of |m1 :+: m2| is the sum of the two, and the duration of |m1 :=: m2| is the maximum of the two. The only tricky part is the duration of a music value that is modified by the |Tempo| atttribute---in this case the duration must be scaled appropriately. Note that the duration of a music value that is conceptually infinite in duration will be |bottom|, since |dur| will not terminate. (Similary, taking the length of an infinite list is |bottom|.) For example: \begin{spec} dur (repeatM (a 4 qn)) ==> dur (a 4 qn :+: repeatM (a 4 qn)) ==> dur (a 4 qn) + dur (repeatM (a 4 qn)) ==> qn + dur (repeatM (a 4 qn)) ==> ... ==> bottom \end{spec} \newpage \section{Super-retrograde} \label{sec:reverse-music} Using |dur| we can define a function |revM| that reverses any |Music| value whose duration is finite (and is thus considerably more useful than |retro| defined earlier): \begin{code} revM :: Music a -> Music a revM n@(Prim _) = n revM (Modify c m) = Modify c (revM m) revM (m1 :+: m2) = revM m2 :+: revM m1 revM (m1 :=: m2) = let d1 = dur m1 d2 = dur m2 in if d1>d2 then revM m1 :=: (rest (d1-d2) :+: revM m2) else (rest (d2-d1) :+: revM m1) :=: revM m2 \end{code} The first three cases are easy, but the last case is a bit tricky. The parallel constructor |(:=:)| implicitly begins each of its music values at the same time. But if one is shorter than the other, then, when reversed, a \emph{rest} must be inserted before the shorter one, to account for the difference. Note that |revM| of a |Music| value whose duration is infinite is |bottom|. (Similary, reversing an infinite list is |bottom|.) \section{Truncating Parallel Composition} Note that the duration of |m1 :=: m2| is the maximum of the durations of |m1| and |m2| (and thus if one is infinite, so is the result). Sometimes we would rather have the result be of duration equal to the shorter of the two. This is not as easy as it sounds, since it may require interrupting the longer one in the middle of a note (or notes). We will define a ``truncating parallel composition'' operator |(/=:)|, but first we will define an auxiliary function |cut| such that |cut d m| is the musical value |m| ``cut short'' to have at most duration |d|: \begin{code} cut :: Dur -> Music a -> Music a cut d m | d <= 0 = rest 0 cut d (Prim (Note oldD p)) = note (min oldD d) p cut d (Prim (Rest oldD)) = rest (min oldD d) cut d (m1 :=: m2) = cut d m1 :=: cut d m2 cut d (m1 :+: m2) = let m1' = cut d m1 m2' = cut (d - dur m1') m2 in m1' :+: m2' cut d (Modify (Tempo r) m) = tempo r (cut (d*r) m) cut d (Modify c m) = Modify c (cut d m) \end{code} Note that |cut| is equipped to handle a |Music| value of infinite duration. With |cut|, the definition of |(/=:)| is now straightforward: \begin{code} (/=:) :: Music a -> Music a -> Music a m1 /=: m2 = cut (min (dur m1) (dur m2)) (m1 :=: m2) \end{code} Unfortunately, whereas |cut| can handle infinite-duration music values, |(/=:)| cannot. This is because |(/=:)| computes the duration of both of its arguments, but if |m| has infinite duration, then |dur m ==> bottom|. If, in a particular context, you know that only one of the two arguments is infinite, and you know which one (say |m1|), it is always possible to do the following: \begin{spec} cut (dur m2) m1 :=: m2 \end{spec} \vspace{.1in}\hrule \begin{exercise}{\em Define a version of |(/=:)| that shortens correctly when either one or the other of its arguments is infinite in duration. Assume that it is not known ahead of time which one is infinite.} \end{exercise} \begin{exercise}{\em Define a version of |(/=:)| that shortens correctly when either one or the other \emph{or both} of its arguments are infinite in duration. When they are both infinite, an infinite-duration result is returned. (This is much harder than the previous exercise.)} \end{exercise} \vspace{.1in}\hrule \section{Trills} \label{sec:trills} A \emph{trill} is an ornament that alternates rapidly between two (usually adjacent) pitches. We will define two versions of a trill function, both of which take the starting note and an interval for the trill note as arguments (the interval is usually one or two, but can actually be anything). One version will additionally have an argument that specifies how long each trill note should be, whereas the other will have an argument that specifies how many trills should occur. In both cases the total duration will be the same as the duration of the original note. Here is the first trill function: \begin{code} trill :: Int -> Dur -> Music Pitch -> Music Pitch trill i sDur (Prim (Note tDur p)) = if sDur >= tDur then note tDur p else note sDur p :+: trill (negate i) sDur (note (tDur-sDur) (trans i p)) trill i d (Modify (Tempo r) m) = tempo r (trill i (d*r) m) trill i d (Modify c m) = Modify c (trill i d m) trill _ _ _ = error "trill: input must be a single note." \end{code} Using this function it is simple to define a version that starts on the trill note rather than the start note: \begin{code} trill' :: Int -> Dur -> Music Pitch -> Music Pitch trill' i sDur m = trill (negate i) sDur (transpose i m) \end{code} The second way to define a trill is in terms of the number of subdivided notes to be included in the trill. We can use the first trill function to define this new one: \begin{code} trilln :: Int -> Int -> Music Pitch -> Music Pitch trilln i nTimes m = trill i (dur m / fromIntegral nTimes) m \end{code} This, too, can be made to start on the other note. \begin{code} trilln' :: Int -> Int -> Music Pitch -> Music Pitch trilln' i nTimes m = trilln (negate i) nTimes (transpose i m) \end{code} Finally, a |roll| can be implemented as a trill whose interval is zero. This feature is particularly useful for percussion. \begin{code} roll :: Dur -> Music Pitch -> Music Pitch rolln :: Int -> Music Pitch -> Music Pitch roll dur m = trill 0 dur m rolln nTimes m = trilln 0 nTimes m \end{code} Figure \ref{fig:ssf} shows a nice use of the trill functions in encoding the opening lines of John Philip Sousa's \emph{Stars and Stripes Forever}. \begin{figure} \begin{code} ssfMel :: Music Pitch ssfMel = line (l1 ++ l2 ++ l3 ++ l4) where l1 = [ trilln 2 5 (bf 6 en), ef 7 en, ef 6 en, ef 7 en ] l2 = [ bf 6 sn, c 7 sn, bf 6 sn, g 6 sn, ef 6 en, bf 5 en ] l3 = [ ef 6 sn, f 6 sn, g 6 sn, af 6 sn, bf 6 en, ef 7 en ] l4 = [ trill 2 tn (bf 6 qn), bf 6 sn, denr ] starsAndStripes :: Music Pitch starsAndStripes = instrument Flute ssfMel \end{code} \caption{Trills in \emph{Stars and Stripes Forever}} \label{fig:ssf} \end{figure} \newpage \section{Grace Notes} \label{sec:grace-notes} In Chapter \ref{ch:interlude} we defined a function to create grace notes. We redefine that function here to include a |Rational| argument that specifies that fraction of the principal note's duration to be used for the grace note's duration: \begin{code} grace :: Int -> Rational -> Music Pitch -> Music Pitch grace n r (Prim (Note d p)) = note (r*d) (trans n p) :+: note ((1-r)*d) p grace n r _ = error "grace: can only add a grace note to a note" \end{code} |grace n r (note d p)| is a |Music| value consisting of two notes, the first being the grace note whose duration is |r*d| and whose pitch is |n| semitones higher (or lower if |n| is negative) than |p|, and the second being the principal note at pitch |p| but now with duration |(1-r)*d|. Note that |grace| places the downbeat of the grace note at the point written for the principal note. Sometimes the interpretation of a grace note is such that the downbeat of the principal note is to be unchanged. In that case, the grace note reduces the duration of the \emph{previous} note. We can define a function |grace2| that takes two notes as arguments, and places the grace note appropriately: \begin{code} grace2 :: Int -> Rational -> Music Pitch -> Music Pitch -> Music Pitch grace2 n r (Prim (Note d1 p1)) (Prim (Note d2 p2)) = note (d1-r*d2) p1 :+: note (r*d2) (trans n p2) :+: note d2 p2 grace2 _ _ _ _ = error "grace2: can only add a grace note to a note" \end{code} \section{Percussion} \label{sec:percussion} Percussion is a difficult notion to represent in the abstract. On one hand, a percussion instrument is just another instrument, so why should it be treated differently? On the other hand, even common practice notation treats it specially, although it has much in common with non-percussive notation. The MIDI standard is equally ambiguous about the treatment of percussion: on one hand, percussion sounds are chosen by specifying an octave and pitch, just like any other instrument; on the other hand these pitches have no tonal meaning whatsoever: they are just a convenient way to select from a large number of percussion sounds. Indeed, part of the General MIDI Standard is a set of names for commonly used percussion sounds. \begin{figure}{\small \begin{code} data PercussionSound = AcousticBassDrum -- MIDI Key 35 | BassDrum1 -- MIDI Key 36 | SideStick -- ... | AcousticSnare | HandClap | ElectricSnare | LowFloorTom | ClosedHiHat | HighFloorTom | PedalHiHat | LowTom | OpenHiHat | LowMidTom | HiMidTom | CrashCymbal1 | HighTom | RideCymbal1 | ChineseCymbal | RideBell | Tambourine | SplashCymbal | Cowbell | CrashCymbal2 | Vibraslap | RideCymbal2 | HiBongo | LowBongo | MuteHiConga | OpenHiConga | LowConga | HighTimbale | LowTimbale | HighAgogo | LowAgogo | Cabasa | Maracas | ShortWhistle | LongWhistle | ShortGuiro | LongGuiro | Claves | HiWoodBlock | LowWoodBlock | MuteCuica | OpenCuica | MuteTriangle | OpenTriangle -- MIDI Key 82 deriving (Show,Eq,Ord,Enum) \end{code}} \caption{General MIDI Percussion Names} \label{fig:percussion} \end{figure} Since MIDI is such a popular platform, we can at least define some handy functions for using the General MIDI Standard. We start by defining the data type shown in Figure \ref{fig:percussion}, which borrows its constructor names from the General MIDI standard. The comments reflecting the ``MIDI Key'' numbers will be explained later, but basically a MIDI Key is the equivalent of an absolute pitch in Euterpea terminology. So all we need is a way to convert these percussion sound names into a |Music| value; i.e.\ a |Note|: \newpage \begin{code} perc :: PercussionSound -> Dur -> Music Pitch perc ps dur = note dur (pitch (fromEnum ps + 35)) \end{code} \syn{|fromEnum| is an operator in the |Enum| class, which is all about enumerations, and was discussed briefly in Section \ref{sec:qualified-types}. A data type that is a member of this class can be \emph{enumerated}---i.e.\ the elements of the data type can be listed in order. |fromEnum| maps each value to its index in this enumeration. Thus |fromEnum AcousticBassDrum| is 0, |fromEnum BassDrum1| is 1, and so on.} For example, here are eight bars of a simple rock or ``funk groove'' that uses |perc| and |roll|: \begin{code} funkGroove = let p1 = perc LowTom qn p2 = perc AcousticSnare en in tempo 3 $ instrument Percussion $ cut 8 $ repeatM ( ( p1 :+: qnr :+: p2 :+: qnr :+: p2 :+: p1 :+: p1 :+: qnr :+: p2 :+: enr) :=: roll en (perc ClosedHiHat 2) ) \end{code} % $ \out{ We can go one step further by defining our own little ``percussion datatype:'' \begin{spec} data Percussion = Perc Dur [NoteAttribute] -- percussion | Pause Dur -- rest | Roll Dur Dur [NoteAttribute] -- roll w/duration | Rolln Int Dur [NoteAttribute] -- roll w/number of strokes \end{spec} whose interpretation is given by: \begin{spec} percLine :: PercussionSound -> [Percussion] -> Music a percLine dsnd l = Instr "Drums" (foldr (dlAux dsnd) (Rest 0) l) where dlAux dsnd (N dur na) = perc dsnd dur na :+: xs dlAux dsnd (R dur) = Rest dur :+: xs dlAux dsnd (Roll sDur dur na) = roll sDur (perc dsnd dur na) :+: xs dlAux dsnd (Rolln nTimes dur na) = rolln nTimes (perc dsnd dur na) :+: dlAux dsnd xs \end{spec} } \vspace{.1in}\hrule \begin{exercise}{\em Find a drum beat that you like, and express it in Euterpea. Then use |repeatM|, |cut|, and |(:=:)| to add a simple melody to it.} \end{exercise} %% \begin{exercise}\label{ex:chrom}{\em %% Define a function |chrom :: Pitch -> Pitch -> Music Pitch| such that %% |chrom p1 p2| is a chromatic scale of quarter-notes whose first pitch %% is |p1| and last pitch is |p2|. If |p1 > p2|, the scale should be %% descending, otherwise it should be ascending. If |p1 == p2|, then the %% scale should contain just one note. (A chromatic scale is one whose %% successive pitches are separated by one absolute pitch, i.e.\ one %% semitone).} %% \end{exercise} %% \begin{exercise}{\em %% Abstractly, a scale can be described by the intervals between %% successive notes. For example, the 8-note major scale can be defined %% as the sequence of 7 intervals |[2,2,1,2,2,2,1]|, and the 12-note %% chromatic scale by the 11 intervals |[1,1,1,1,1,1,1,1,1,1,1]|. Define a %% function |mkScale :: Pitch -> [Int] -> Music Pitch| such that %% |mkScale p ints| is the scale beginning at pitch |p| and having the %% intervallic structure |ints|.} %% \end{exercise} %% \begin{exercise}{\em %% Write the melody of ``Fr\`{e}re Jacques'' (or, ``Are You Sleeping'') in %% Euterpea. Try to make it as succinct as possible. Then, using %% functions already defined, generate a four-part round, i.e.\ four %% identical voices, each delayed successively by two measures. Use a %% different instrument to realize each voice.} %% \end{exercise} \vspace{.1in}\hrule \section{A Map for Music} \label{sec:music-map} Recall from Chapter \ref{ch:poly} the definition of |map|: \begin{spec} map :: (a -> b) -> [a] -> [b] map f [] = [] map f (x:xs) = f x : map f xs \end{spec} This function is defined on the list data type. Is there something analogous for |Music|? I.e.\ a function: \begin{spec} mMap :: (a -> b) -> Music a -> Music b \end{spec} Such a function is indeed straightforward to define, but it helps to first define a map-like function for the |Primitive| type: \begin{code} pMap :: (a -> b) -> Primitive a -> Primitive b pMap f (Note d x) = Note d (f x) pMap f (Rest d) = Rest d \end{code} With |pMap| in hand we can now define |mMap|: \begin{code} mMap :: (a -> b) -> Music a -> Music b mMap f (Prim p) = Prim (pMap f p) mMap f (m1 :+: m2) = mMap f m1 :+: mMap f m2 mMap f (m1 :=: m2) = mMap f m1 :=: mMap f m2 mMap f (Modify c m) = Modify c (mMap f m) \end{code} Just as |map f xs| for lists replaces each polymorphic element |x| in |xs| with |f x|, |mMap f m| for |Music| replaces each polymorphic element |p| in |m| with |f p|. As an example of how |mMap| can be used, suppose that we introduce a |Volume| type for a note simply as: \begin{code} type Volume = Int \end{code} and then wish to convert a value of type |Music Pitch| to a value of type |Music (Pitch,Volume)| -- that is, we wish to pair each pitch with a volume attribute. We can define a function to do so as follows: \begin{code} addVolume :: Volume -> Music Pitch -> Music (Pitch,Volume) addVolume v = mMap (\p -> (p,v)) \end{code} \vspace{.1in}\hrule \begin{exercise}{\em Using |mMap|, define a function: \begin{spec} scaleVolume :: Rational -> Music (Pitch,Volume) -> Music (Pitch,Volume) \end{spec} such that |scaleVolume s m| scales the volume of each note in |m| by a factor of |s|.} \end{exercise} \vspace{.1in}\hrule \newpage \section{A Fold for Music} \label{sec:music-fold} We can also define a fold-like operator for |Music|. But whereas the list data type has only two constructors (the nullary constructor |[]| and the binary constructor |(:)|), |Music| has \emph{four} constructors, and thus we define: \begin{code} mFold :: (b->b->b) -> (b->b->b) -> (Primitive a -> b) -> (Control -> b -> b) -> Music a -> b mFold (+:) (=:) f g m = let rec = mFold (+:) (=:) f g in case m of Prim p -> f p m1 :+: m2 -> rec m1 +: rec m2 m1 :=: m2 -> rec m1 =: rec m2 Modify c m -> g c (rec m) \end{code} This somewhat unwieldy function basically takes apart a |Music| value and puts it back together with different constructors. Indeed, note that: \begin{spec} mFold (:+:) (:=:) Prim Modify == id \end{spec} Although intuitive, proving this property requires induction, a proof technique that we will discuss in Chapter \ref{ch:induction}. To see how |mFold| might be used, note first of all that it is more general than |mMap|---indeed, |mMap| can be defined in terms of |mFold| like this: \begin{spec} mMap :: (a -> b) -> Music a -> Music b mMap f = mFold (:+:) (:=:) g Modify where g (Note d x) = note d (f x) g (Rest d) = rest d \end{spec} More interestingly, we can use |mFold| to more succinctly define functions such as |dur| from Section \ref{sec:duration}: \begin{spec} dur :: Music a -> Dur dur = mFold (+) max getDur modDur where getDur (Note d _) = d getDur (Rest d) = d modDur (Tempo r) d = d/r modDur _ d = d \end{spec} \vspace{.1in}\hrule \begin{exercise}{\em Redefine |revM| from Section \ref{sec:reverse-music} using |mFold|.} \end{exercise} \begin{exercise}{\em Define a function |insideOut| that inverts the role of serial and parallel composition in a |Music| value. Using |insideOut|, see if you can (a) find a non-trivial value |m :: Music Pitch| such that |m == insideOut m| and (b) find a value |m :: Music Pitch| such that: \begin{spec} m :+: insideOut m :+: m \end{spec} sounds interesting. (You are free to define what ``sounds interesting'' means.)} \end{exercise} \vspace{.1in}\hrule \section{Crazy Recursion} With all the functions and data types that we have defined, and the power of recursion and higher-order functions at our finger tips, we can start to do some wild and crazy things. Here is just one such idea. Let's define a function to recursively apply transformations |f| (to elements in a sequence) and |g| (to accumulated phrases) some specified number of times: \begin{code} rep :: (Music a -> Music a) -> (Music a -> Music a) -> Int -> Music a -> Music a rep f g 0 m = rest 0 rep f g n m = m :=: g (rep f g (n-1) (f m)) \end{code} With this simple function we can create some interesting phrases of music with very little code. For example, let's use |rep| three times, nested together, to create a ``cascade'' of sounds: \begin{code} run = rep (transpose 5) (delay tn) 8 (c 4 tn) cascade = rep (transpose 4) (delay en) 8 run cascades = rep id (delay sn) 2 cascade \end{code} and then make the cascade run up, and then down: \begin{code} final = cascades :+: revM cascades \end{code} What happens if we reverse the |f| and |g| arguments? \begin{code} run' = rep (delay tn) (transpose 5) 8 (c 4 tn) cascade' = rep (delay en) (transpose 4) 8 run' cascades' = rep (delay sn) id 2 cascade' final' = cascades' :+: revM cascades' \end{code} \newpage \vspace{.1in}\hrule \begin{exercise}{\em Consider this sequence of 8 numbers: \begin{spec} s1 = [ 1, 5, 3, 6, 5, 0, 1, 1 ] \end{spec} One might interpret this as a sequence of pitches, i.e.\ a melody. Another way to represent this sequence is as a sequence of 7 intervals: \begin{spec} s2 = [ 4, -2, 3, -1, -5, 1, 0 ] \end{spec} Together with the starting pitch (i.e.\ 1), this sequence of intervals can be used to reconstruct the original melody. But, with a suitable transposition to eliminate negative numbers, it can also be viewed as another melody. Indeed, we can repeat the process: |s2| can be represented by this sequence of 6 intervals: \begin{spec} s3 = [ -6, 5, -4, -4, 6, -1 ] \end{spec} Together with the starting number (i.e.\ 4), |s3| can be used to reconstruct |s2|. Let's continue the process: \begin{spec} s4 = [ 11, -9, 0, 10, -7 ] s5 = [ -20, 9, 10, -17 ] s6 = [ 29, 1, -27 ] s7 = [ -28, -28 ] s8 = [ 0 ] \end{spec} Now, if we take the first element of each of these sequences to form this 8-number sequence: \begin{spec} ic = [ 0, -28, 29, -20, 11, -6, 4, 1 ] \end{spec} then it alone can be used to re-create the original 8-number sequence in its entirety. Of course, it can also be used as the original melody was used, and we could derive another 8-note sequence from it---and so on. We will refer to the list |ic| as the ``interval closure'' of the original list |s1|. Your job is to: \begin{enumerate}[a)] \item Define a function |toIntervals| that takes a list of |n| numbers, and generates a list of |n| lists, such that the $i^{th}$ list is the sequence |si| as we defined them above. \item Define a function |getHeads| that takes a list of |n| lists and returns a list of |n| numbers such that the $i^{th}$ element is the head of the $i^{th}$ list. \item Compose the above two functions in a suitable way to define a function |intervalClosure| that takes an |n|-element list and returns its interval closure. \item Define a function |intervalClosures| that takes an |n|-element list and returns an infinite sequence of interval closures. \item Now for the open-ended part of this exercise: Interpret the outputs of any of the functions above to create some ``interesting'' music. \end{enumerate} } \end{exercise} \begin{exercise}{\em Do something wild and crazy with Euterpea.} \end{exercise} \vspace{.1in}\hrule