[Haskell-beginners] some Data.Map questions

David McBride dmcbride at neondsl.com
Fri Aug 19 05:46:29 CEST 2011


Maybe something like this:

instance Eq Loc where
  a == b = ...
instance Ord Loc where
  compare a b = ...

data Instruction = InstrNote (Loc, Note) | InstrPD (Loc, PlayDirection)

write a function that will combine the notes and playdirections into
one list of everything sequentially.

combineNotesDirs :: [(Loc,Note)] -> [(Loc,PlayDirection)] -> [Instruction]
combineNotesDirs [] [] = []
combineNotesDirs [] (d:ds) = undefined --you can figure this out
combineNotesDirs (n:ns) [] = undefined
combineNotesDirs notes@(n:ns) dirs@(d:ds)
  | fst d <= fst n = InstrPD d : (zipNotesDirs notes ds)
  | otherwise      = InstrNote n : (zipNotesDirs ns dirs)

Then loop over that and store them as a map.  Traverse the list, keep
track of the playdirection at each entry, and then accumulate the
current direction and note at each note entry into a new map.

instructionlist2map :: [Instruction] -> Map Loc (Note, PlayDirection)

I'm sure this could be cleaned up a bit, but is that sort of what you
were looking for?

On Thu, Aug 18, 2011 at 8:57 PM, Dennis Raddle <dennis.raddle at gmail.com> wrote:
> Here's my problem. It's from music. I have a program which reads a
> MusicXML file and creates a realization (performance) via software
> synthesis. Currently I'm working on pizzicato and arco markings. Let
> me explain. A string instrument can play in a number of ways. To name
> two of them, in "pizzicato" playing, the musician plucks a string,
> while in "arco" the musician bows the string. Pizzicato and arco
> markings appear above notes in the sheet music. (Therefore they appear
> in the MusicXML which is a representation of sheet music.) If a piece
> has no marking at all, or no marking until later in the piece, "arco"
> is assumed. When a "pizz." (the usual abbreviation as it appears in
> sheet music) occurs, then the note under the marking should be played
> pizzicato, and *so should all following notes until another marking.*
> When an "arco" occurs, likewise that note and all following notes
> until the next marking should be played arco.
>
> The goal is to determine, for every note in the score, how it should be played.
>
> Here's some of the code I have.
>
> data Loc = <... representation of a location (measure # and beat) in
> the score ..>
>
> data Note = <.. all data describing a note in the score ... >
>
> -- this structure holds all notes. there can be one or many notes at
> each location
> notes :: Map Loc [Note]
>
> -- pizz. and arco are called, in MusicXML terms, a <direction> of type <words>
> -- They are only two of many such words.
> data DirectionWords = DirectionWords String
>
> -- this structure holds all direction-words in the score
> directionWords :: Map Loc [DirectionWords]
>
> The following code is not a complete solution, but it illustrates the
> lovely mapAccum function in Data.Map.
>
> Suppose we have
>
> data PlayDirection = PlayPizz
>                           | PlayArco
>
> To determine the direction in effect at each location in
> 'directionWords' (not in 'notes' which is what we really want) we can
> use mapAccum in Data.Map.
>
>
> directionInEffect :: Map Loc PlayDirection
> directionInEffect = snd $ mapAccum step PlayArco directionWords
>  where
>    step :: PlayDirection -> [DirectionWords] -> (PlayDirection,PlayDirection)
>    step dir words
>      | any (== DirectionWords "arco") words = (PlayArco, PlayArco)
>      | any (== DirectionWords "pizz.") words = (PlayPizz, PlayPizz)
>      | otherwise = (dir, dir)
>
>
> But what I really need to do is determine the direction in effect at
> each location in 'notes'
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>



More information about the Beginners mailing list