12

我已经阅读了有关 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 的库或扩展可以使这种方法编写起来不那么混乱?

4

2 回答 2

6

似乎Data.Has封装了很多你正在寻找的东西。在他们的词汇表中,我认为他们的Knowstype-class 更接近于 your Has,并且它也为注入提供了签名。

他们还使用标签机制来处理我认为您尚未考虑过的问题:包含具有相同类型的字段的记录。他们使用类型级别的标签来消除歧义。

为方便起见,似乎还有一些支持在Has-THHas中为带有模板 Haskell 的实例提供生成器

您可以在 Oleg the Type Magician 的作品中找到更多类型级别的标签和其他与唱片相关的材料,例如OOHaskell(也与 Ralf Lämmel 合作)。

于 2012-05-03T09:10:42.987 回答
0

data-accessor-template 至少可以帮助编写 set/get 访问器。也许有些人可以想出模板 Haskell 代码来为每个记录字段名称生成类和实例。但是,我自己不使用 Template Haskell 的东西。它限制你使用 GHC,甚至限制特定的 GHC 版本,因为 Template Haskell 在不同的 GHC 版本之间发生变化。每个模块拥有一个(主要)记录确实是有回报的。

于 2012-05-10T10:26:34.410 回答