
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'