我继承了具有相同名称但不同类型的函数的类型类。
代码:
class Equatable a where
(==) :: a -> a -> Bool
class Equatable key => Entity key where
(==) :: (Entity key) -> (Entity key) -> Bool
错误:
'=='
的多个声明
我正在尝试模拟C#中的下一个代码:
public class Equatable<T>
{
public static bool ==(T type1, T type2)
{ … }
}
public class Entity<TKey> : Equatable<TKey>
{
public static bool ==(Entity<TKey> type1, Entity<TKey> type2)
{ … }
}
答案 0 :(得分:3)
正如一些评论者所指出的那样,Haskell中的类是与面向对象的语言(如C#)中的类完全不同的概念。 This article在解释差异方面做得比我自己做得更好,我强烈建议您阅读它,但要点是,当您定义OO类时,您正在定义具有特定实现的特定数据类型。该类型的方法。另一方面,Haskell类型类本身不是类型,它们是可以实现多种类型的抽象接口。特别是,类型类不包含它们声明的功能的实现。从某种意义上讲,这是类型类的全部要点。它们使您可以编写可在实现类似功能的多种不同类型上运行的代码,而不必关心在任何给定时间使用的实现,类似于鸭子类型或Java的抽象类。由于所有这些,在两个不同类型类中的方法中使用相同名称的想法永远不是一个好主意。对于任何编程语言中的不同功能,只有相同的名称才有意义,如果这些功能仅仅是同一基本操作的不同实现,但是类型类不包含任何实现。如果要在不同的类型类中定义不同的函数,那是因为您要描述的操作是完全独立的,而与它们的实现无关。
对于您的特定情况,听起来像您希望Entity
是一个携带某些数据的对象,该数据与(==)
的特定实现相关。在这种情况下,您实际上实际上Entity
是一种实现 Equatable
(或者最好是Eq
来自具有完全相同定义的标准库)的数据类型。 。这样,当您使用==
比较类型Entity
的对象时,将使用在实现==
时给出的Equatable
的特定定义(或{ {1}}代表Eq
,并且当您在其他类型的对象上使用Entity
时,它将使用这些类型各自的实现。
答案 1 :(得分:0)
C#使用一种构造来实现两个不同的概念。哈斯克尔
将两者分开; (==)
由类型类定义,而使用(==)
的数据由类型定义。
data Entity a = Entity a -- A new type
instance Eq a => Entity A where -- An instance of a typeclass for that type
(Entity x) == (Entity y) = x == y
Haskell可以为您派生Eq
,从而省去了您的工作量
明确定义实例的过程。
data Entity a = Entity a deriving Eq