我正在学习Haskell,我编写了一个C++头文件的格式化程序。首先,我将所有类成员解析为类成员集合,然后将其传递给格式化程序。为了表示类成员,我有:
data ClassMember = CmTypedef Typedef |
CmMethod Method |
CmOperatorOverload OperatorOverload |
CmVariable Variable |
CmFriendClass FriendClass |
CmDestructor Destructor
因为某些格式样式的特殊性,我需要以这种方式分类类成员。
令我烦恼的问题是,要将定义为类成员类型的任何函数“拖放”到ClassMember
级别,我必须编写大量冗余代码。例如:
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
另一方面,我肯定希望有一个 ClassMember
对象列表(至少我是这么认为的),因此将其定义为:
data ClassMember a = ClassMember a
instance Formattable ClassMember a
format (ClassMember a) = format a
似乎没有这个选项。
我正在考虑的替代方案有:
在
ClassMember
中存储对应类型上定义的函数,而不是对象实例本身,这些函数是格式化程序所需的。我认为这种方法会破坏模块化,因为表示为[ClassMember]
的解析结果需要意识到它们的所有用途。将
ClassMember
定义为存在类型,因此[ClassMember]
不再是问题。我怀疑这种设计是否足够严格,并且我需要在定义中指定所有约束条件,例如data ClassMember = forall a . Formattable a => ClassMember a
。另外,我希望找到一种不使用扩展的解决方案。
我现在采用的方式在 Haskell 中是否正确,还是有更好的方法?
Formattable
和Prettifyable
类型类?你会格式化不是ClassMember
的东西吗? - Benjamin Hodgsondata FormattableItem = FiClassMember ClassMember (Maybe SingleLineComment) | FiSingleLineComment SingleLineComment | FiComment Comment | FiScopeModifier AccessModifier
。格式化规则有点复杂:ClassMember
对象由其他FormattableItem
对象分组,并且在组内它们也相互依赖。 - AdelNick