
On Sun, 4 Jul 2010, Michael Mossey wrote:
I can solve a simpler problem which is
-- Given a note with tieNext set, and a list of notes, find -- the end Loc of the last note in the chain. Only notes -- with the same pitch as 'firstNote' are considered when looking -- for the chain of notes. computeSoundedEnd :: Item -> [Item] -> Loc computeSoundedEnd firstNote notes = compSndEnd (pitch firstNote) notes
compSndEnd :: Pitch -> [Item] -> Loc compSndEnd _ [] = error "tie chain doesn't come to completion" compSndEnd p (n:ns) = if pitch n == p then if tieNext n then if tiePrior n then compSndEnd p ns else error "illegal tie chain" else if tiePrior n then end n else error "illegal tie chain" else compSndEnd p ns
The thing that is hard for me to understand is how, in a functional paradigm, to update the entire Doc by chasing down every tie and making all necessary updates.
You will certainly not be able to make use of foldl or foldr, but you may use a manual recursion instead. Just like computeAllEnds :: [Item] -> [Item] computeAllEnds [] = [] computeAllEnds (x:xs) = x{loc = computeSoundedEnd x xs} : computeAllEnds xs Cf. the code in Haskell to turn MIDI events into notes with duration: http://code.haskell.org/haskore/revised/core/src/Haskore/Interface/MIDI/Read... However, that's a bit more complicated, since it must respect interim tempo changes.