[Haskell-cafe] music-related problem

Henning Thielemann lemming at henning-thielemann.de
Sun Jul 4 15:13:05 EDT 2010

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:
  However, that's a bit more complicated, since it must respect interim 
tempo changes.

More information about the Haskell-Cafe mailing list