学习Haskell,我写了一个C++头文件的格式化程序。首先,我将所有班级成员解析成a-collection-of-class-members然后传递给格式化例程。为了表示类成员我有Haskell中的数据类型设计
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
没有对象实例本身,而是在相应的类型,这是由格式化程序需要定义的功能。这种方法打破了IMO的模块化,因为由[ClassMember]
表示的解析结果需要知道所有的用法。定义
ClassMember
作为存在类型,所以[ClassMember]
已不再是一个问题。我怀疑这个设计是否足够严格,而且我需要在定义中指定所有约束条件,如data ClassMember = forall a . Formattable a => ClassMember a
。另外,我更喜欢不使用扩展的解决方案。
是我正在做一个正确的方式来做到这一点在Haskell或有更好的办法吗?
为什么你首先需要'Formattable'和'Prettifyable'类型的类吗?你是否想要格式化一些不是'ClassMember'的东西? – 2014-11-04 21:16:14
@BenjaminHodgson:是的,这是问题所在。实际要格式化的东西是'data FormattableItem = FiClassMember ClassMember(Maybe SingleLineComment)| FiSingleLineComment SingleLineComment | FiComment评论| FiScopeModifier AccessModifier'。格式化规则有点花哨:“ClassMember”对象被其他“FormattableItem”对象分割成组,并且在组内也相互依赖。 – AdelNick 2014-11-05 09:20:32