【发布时间】:2013-07-19 18:19:02
【问题描述】:
我想用几个默认方法实现Type Class,但我遇到了一个错误,我不能在type classes 定义中使用record selectors。
下面的代码基本上创建了type class,它定义了add函数,它应该在一些data type的repr记录中添加一个元素。代码如下:
import qualified Data.Graph.Inductive as DG
class Graph gr a b where
empty :: DG.Gr a b
empty = DG.empty
repr :: gr -> DG.Gr a b
-- following function declaration does NOT work:
add :: a -> gr -> gr
add el g = g{repr = DG.insNode el $ repr g}
编译器报错:
repr is not a record selector
In the expression: g {repr = DG.insNode el $ repr g}
In an equation for add:
add el g = g {repr = DG.insNode el $ repr g}
是否可以在 Haskell 中声明这样的方法?
澄清
我需要这样的设计,因为我有一些data types,它们的行为方式类似。可以说,我们得到了 A、B 和 C data types。他们每个人都应该有一个记录repr :: DG.Gr a b,其中a 和b 对于A、B 和C 中的每一个都是不同的。
A、B 和C 共享相同的功能,例如add 或delete(基本上添加或删除元素以记录repr)。如果这些数据类型共享很多函数,那么实现 type class 中的函数并创建此 type class 的实例是有意义的 - 这些函数将为我们的每个 data type 自动实现。
另外,我希望其中一些data types(假设我想要B)在调用add 函数时表现得略有不同。在将type class 中的instance 制作为B 时,很容易实现此行为。
【问题讨论】:
-
答案是“不”,但“有点,使用镜头”,但更重要的是,我觉得这里对类的用途存在根本性的误解。如果您说为什么要开设这样的课程,那将很有帮助;我们也许可以提出一个更惯用的替代方案。
-
@DanielWagner - 我已经为我要解决的问题添加了说明 - 我希望现在已经足够清楚了,我为什么要这样做:)
-
查看我的更新答案。在第二个示例中,我使用
update方法执行实际更新(可以在实例中使用该记录更新语法来实现),第三个示例使用Control.Lens。 -
@JJJ 我认为镜头是我要找的!谢谢!
标签: haskell types record typeclass