
Continuing Keith's self-reply ... the Music type involves types other than Music; so it is fair to say that ultimately you would need generalised folds extended to the case of *systems* of datatypes (cf. "Dealing with large bananas"). Imagine for example getPitches :: Music -> [Pitch]. Even if a function, be it getNotes or otherwise, investigates patterns in addition to just looking at arguments obtained by recursive folding, then this function can be generally turned into a simple fold. This is the step of going from paramorphisms to catamorphisms using the infamous tupling technique that goes back to L. Meertens I think :-). (I am not sure that this the obvious way to think of these things.) Finally, the getNotes function only recurses into Music but not into the structure of Notes, and so I would actually prefer to have a return type [(Pitch,Octave,Duration)] rather than [Music] just to be sure that I am extracting notes and not whatever kind of Music. Need a banana, now :-) Ralf Keith Wansbrough wrote:
[replying to self, oops]
Oops, I didn't look closely enough at this line. As written, this *isn't* a fold because it examines the item (Note _ _ _ :: Music) directly rather than just looking at its arguments. But (a) it's academic in this case - since none of the arguments are recursive, you can just write
getNotes (Note p o d) = [Note p o d]