[Haskell-beginners] some Data.Map questions
Dennis Raddle
dennis.raddle at gmail.com
Fri Aug 19 02:57:33 CEST 2011
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'
More information about the Beginners
mailing list