
On 4 March 2011 06:32, Jason Dusek
-- From https://github.com/solidsnack/bash/blob/c718de36d349efc9ac073a2c7082742c4560...
data Annotated t = Annotated t (Statement t) data Statement t = SimpleCommand Expression [Expression] | ... | IfThen (Annotated t) (Annotated t) | ...
I use this a variant of approach quite extensively and it works well for me. My scheme is: data Statement t = SimpleCommand Expression [Expression] | ... | IfThen (t (Statement t)) (t (Statement t)) | ... This is a slightly more efficient representation because it lets you unpack the "t" field of your Annotated data constructor. For example, what would in your system would be: type MyStatement = Statement (Int, Int) Would in my system be: data Ann s = Ann Int Int s type MyStatement = Statement Ann i.e. instead of allocating both a Statement and a (,) at each level we allocate just a Ann at each level. In this system you will probably find it convenient to have a typeclass inhabited by each possible annotation type: class Copointed t where extract :: t a -> a instance Copointed Ann where extract (Ann _ _ x) = x Anyway, this is only a minor efficiency concern -- your scheme looks solid to me as well. Cheers, Max