Learning Haskell, I write a formatter of C++ header files. First, I parse all class members into a-collection-of-class-members which is then passed to the formatting routine. To represent class members I have
data ClassMember = CmTypedef Typedef |
CmMethod Method |
CmOperatorOverload OperatorOverload |
CmVariable Variable |
CmFriendClass FriendClass |
CmDestructor Destructor
(I need to classify the class members this way because of some peculiarities of the formatting style.)
The problem that annoys me is that to "drag" any function defined for the class member types to the ClassMember level, I have to write a lot of redundant code. For example,
instance Formattable ClassMember where
format (CmTypedef td) = format td
format (CmMethod m) = format m
format (CmOperatorOverload oo) = format oo
format (CmVariable v) = format v
format (CmFriendClass fc) = format fc
format (CmDestructor d) = format d
instance Prettifyable ClassMember where
-- same story here
On the other hand, I would definitely like to have a list of ClassMember objects (at least, I think so), hence defining it as
data ClassMember a = ClassMember a
instance Formattable ClassMember a
format (ClassMember a) = format a
doesn't seem to be an option.
The alternatives I'm considering are:
Store in
ClassMembernot object instances themselves, but functions defined on the corresponding types, which are needed by the formatting routine. This approach breaks the modularity, IMO, as the parsing results, represented by[ClassMember], need to be aware of all their usages.Define
ClassMemberas an existential type, so[ClassMember]is no longer a problem. I doubt whether this design is strict enough and, again, I need to specify all constraints in the definition, likedata ClassMember = forall a . Formattable a => ClassMember a. Also, I would prefer a solution without using extensions.
Is what I'm doing a proper way to do it in Haskell or there is a better way?
FormattableandPrettifyabletype classes in the first place? Are you ever going toformatsomething that's not aClassMember?data FormattableItem = FiClassMember ClassMember (Maybe SingleLineComment) | FiSingleLineComment SingleLineComment | FiComment Comment | FiScopeModifier AccessModifier. The formatting rules are a bit fancy:ClassMemberobjects are splitted into groups by otherFormattableItemobjects and within the group they also depend on each other.