
I know this doesn't answer your question, but for this example, it might be easier to use some kind of iterator. In this example:
getNotes :: Music -> [Music] getNotes n@(Note _ _ _) = [n] getNotes (PlayerPar m1 m2) = getNotes m1 ++ getNotes m2 -- etc etc
count_notes = length . getNotes
But of course every function of this form *is a fold* and can be written as such.
Consider the length function, for example:
-- remember lists could be defined by
-- something like the following if they weren't already built in:
-- data [a] = (::) a [a] | []
length :: [a] -> Int
length (x::xs) = 1 + length xs
length [] = 0
This is just a fold:
length xs = foldr (\x r -> 1 + r) 0 xs
or in other words
length = foldr (\x r -> 1 + r) 0
You can see how the two correspond: the first argument corresponds to the first line of the definition, and the second argument corresponds to the second line of the definition.
Now go and do the same for Music.
--KW 8-)
--
Keith Wansbrough