我已经阅读了Haskell记录的一些问题,特别是同一模块中的两个元素不能具有相同名称的事实。
我知道你可以通过单独的模块解决这个问题,但我不想那样做,而是尝试了这种方法:
class HasX a where
x :: a -> X
data D1 = D1 { d1_x :: X, ... }
instance HasX D1 where
x = d1_x
data D2 = D2 { d2_x :: X, ... }
instance HasX D2 where
x = d2_x
(这只是获取,而不是设置,我当然需要编写更多代码来进行设置)。
然而,似乎所有这些的类和实例声明看起来像是样板文件,应该可以使用模板haskell或其他东西来消除。
是否存在GHC的库或扩展,这使得这种方法不那么混乱?
答案 0 :(得分:6)
似乎Data.Has封装了很多你正在寻找的东西。在他们的词汇表中,我认为他们的Knows
类型类更接近您的Has
,并且它也提供了注射的签名。
他们还使用标签机制来处理我认为您尚未考虑的问题:包含具有相同类型的字段的记录。他们使用类型级标签来消除歧义。
为方便起见,似乎还有一些支持为Has-TH
中的模板Haskell的Has
实例提供了一个生成器。
您可以在Oleg the Type Magician的作品中找到更多类型级别的标签和其他与唱片相关的材料,例如OOHaskell(也与RalfLämmel合作)。
答案 1 :(得分:0)
data-accessor-template至少可以帮助编写set / get访问器。也许有些人可以提出模板Haskell代码来为每个记录字段名称生成类和实例。 但是,我自己不使用Template Haskell的东西。它限制你使用GHC,甚至是特定的GHC版本,因为Template Haskell在不同的GHC版本之间发生变化。每个模块有一个(主要)记录真的得到回报。