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.lhs
However, that's a bit more complicated, since it must respect interim tempo changes.
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to