首页 > 解决方案 > 使用同名函数继承类型类

问题描述

我继承了具有相同名称但类型不同的函数的类型类。

代码:

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)
    { … }
}

标签: haskell

解决方案


正如一些评论者所指出的,Haskell 中的类型类与 C# 等面向对象语言中的类是一个非常不同的概念。这篇文章在解释差异方面做得比我自己做得更好,我强烈建议你阅读它,但要点是,当你定义一个 OO 类时,你是在定义一个特定的数据类型,其中包含方法的具体实现那种。另一方面,Haskell 类型类本身不是类型,它们是多种类型可以实现的抽象接口。特别是,类型类不携带它们声明的函数的实现. 从某种意义上说,这就是类型类的全部意义所在。它们允许您编写可以在实现相似功能的多种不同类型上运行的代码,而不必关心在任何给定时间您正在使用哪种实现,类似于鸭子类型或 Java 的抽象类。由于所有这些,在两个不同类型类中使用相同名称的方法绝不是一个好主意。唯一一次在任何编程语言中为不同的函数使用相同的名称是有意义的,如果这些函数仅仅是相同基本操作的不同实现,但同样,类型类不携带任何实现。如果您在不同的类型类中定义不同的函数,那是因为您描述的是完全独立的操作,而不管它们的实现如何。

至于您的具体情况,听起来您想Entity成为一个携带某些数据的对象,这些数据与(==). 在这种情况下,您实际上是Entity一种实现 Equatable的数据类型(或者最好Eq来自具有完全相同定义的标准库)。这样,当您用于==比较 type 的对象时Entity,它们将使用==您在实现Equatable(或Eq) for时给出的特定定义进行比较Entity,当您==在其他类型的对象上使用时,它将使用这些类型各自的实现。


推荐阅读