假设我有一个简单的类(class)AClass
与公共(public)成员 f1
可以被覆盖。定义AClass
的新实例的方法有哪些?与另一位成员 f2
,少了复制AClass
的源代码?玩具代码如下:
class AClass a where
f1 :: a -> Int
data Val = I Int
instance AClass Val where
f1 x = 0
-- the method below can't be added as it is not public member of AClass
-- f2:: a -> Float
-- f2 x = 0.0
我环顾四周,但没有找到任何关于如何做到这一点的明确示例(即,我可以很好理解的示例 - 清晰度是相对的)。有哪些可能的方法?闭包,新类型声明还是其他?使用上面的玩具代码演示该技术将很有帮助 - 您可以更改
data
声明等(例如,用 newtype
周围的 Int
包装器替换它)但上面代码中唯一不可变的是 AClass
的类声明.这是因为假设该类已经由库编写者编写,因此我无法触及它。最终结果应该是另一个继承 AClass
优点的玩具代码。 , 并添加 f2
成员。当然,在这样的覆盖类中会有一些警告。但是,它有助于了解什么是可能的,以及如何。
-- 更新 --
下面的工作代码 - 归功于 Ben 和 mergeconflict 提出了解决方案 - 缺少的部分很少 - 填写如下:
class AClass a where
f1 :: a -> Int
class (AClass a) => BClass a where
f2 :: a -> Float
data Val = I Int
instance AClass Val where
f1 _ = 0
instance BClass Val where
f2 _ = 0.0
最佳答案
你想达到什么目的?
您有一个类型 Val
,您将其作为 AClass
的实例.您可以定义任意数量的使用 Val
的函数。与类(class)无关。停止尝试在 instance
中定义它们宣言。
如果您期望能够拥有 AClass
的一个特定实例有一个额外的 f2
函数,然后在使用 AClass
的函数中使用实例并让他们能够调用f2
……这太 absurd 了。根据定义,唯一已知的对所有人都通用的东西AClass
实例是在 AClass
中声明的东西.如果您只知道某个值是 AClass
的实例类型的成员, 你不能用它做任何你不能用 AClass
的所有实例做的事情。 .您不能调用任何特定于某些实例的额外内容。
如果你想创建一个支持所有操作的新类 AClass
和 f2
一样好, 并有 Val
成为那个新类的一个实例......然后你就这样做。
class AClass a => AnotherClass a where
f2 :: a -> Float
instance AnotherClass Val where
f2 x = 0.0
关于haskell - 用新成员覆盖类实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8514527/