
Thank you all for your advice so far. I went back and tried to simplify my code, but I'm still stuck. The basic idea I want is something like an arbitrary tree structure, where MetaSines are the branches containing Sines, and Sines are the leaves containing strings. I want to recurse through the tree and pick up all the leaf strings, but only if that branch/leaf is "on" for that time. Here's my second attempt at the code: data ISine = Sine Integer Integer Integer String | MetaSine Integer Integer Integer [ISine] letter (Sine _ _ _ l) = l sub_sines (MetaSine _ _ _ xs) = xs period p _ _ _ = p offset _ o _ _ = o threshold _ _ t _ = t on :: Integer->ISine->Bool on time (p o t x) = (mod (time-(offset p o t x)) (period p o t x)) < (threshold p o t x) act time (MetaSine p o t s) |on time (p o t s) = foldr (++) (map (act time) (sub_sines p o t s)) |otherwise = [] act time (Sine p o t l) |on time p o t l = [letter p o t l] |otherwise = [] the on, period, offset, and threshold functions should work exactly the same for Sine and MetaSine, so I'd prefer to only write them once. But the act function needs to differentiate: for a Sine, it just returns a singleton list if on is true, or an empty list otherwise; but for a Metasine, it needs to get the list of all the strings in Sine objects in it's sub_sines field. It only does this if it's on. For example, let's say A / | \ B C D / | / | \ E F G H I If A, C, D, E, F and I are all on, only the strings of Sines C and I should be joined to make a to element list. If everything is on, C, E, F, G, H, I will all be joined. Anyway, the above code still doesn't work; there's a parse error for the definition of on. I don't think my arguments are right somehow. I appreciate your collective patience and expertise, and hope you can put me on the right track. Thomas