我什么时候应该按类型 类 或其他方式定义多态函数?

When shall I define polymorphic functions by type classes or by some other ways?

我想弄清楚类型 class 的用途,如果不使用类型 class 还有什么?

类型class是一种定义多态函数的方法吗?

类型class是定义多态函数的唯一方法吗?例如:

class Eq a where
    (==), (/=) :: a -> a -> Bool
    x /= y  =  not (x == y)

instance Eq Bool where 
    False == False  =  True 
    True  == True   =  True 
    _     == _      =  False

我可以在不使用类型 class Eq 的情况下为 Bool(和任何其他类型)定义 ==/= 吗?

如果有其他方式,我什么时候应该使用哪种方式来定义多态函数,使用类型 class 还是使用其他方式?

OOP 中的多态函数与 haskell 中的多态函数之间存在差异,我之所以这样说是因为 OOP 中通常使用术语 "polymorphism "。

例如,列表上的函数是多态的:

cons:: a -> [a] -> [a]
cons x xs = x:xs

其中 a 是多态类型,那里没有类型类。

顺便说一句,有一种方法可以快速实现类型类,默认情况下,例如EqShow,例如:

data MBool = MTrue | MFalse deriving (Eq, Show)

所以,不同之处在于类型类是一个约束,想象一下这个带有列表的函数:

mapShow :: Show a =>  [a] -> [String]
mapShow = map show

不一样了,因为现在a是有限制的,不能是任何"a"。它应该实现类型类 Show.

总而言之,您可以看到 cons 函数中的 a 类型比 mapShow 函数中的 Show => a -> a 类型更通用或更抽象。

Is type class a way to define polymorphic functions?

,就是一个的方式。但不是唯一的方法。例如 参数多态性 只是意味着如果你定义一个像 init :: [a] -> [a] 这样的函数,它将适用于任何 a。类型 类 用于 ad-hoc 多态性 :根据类型,实现可能完全不同。这与 参数多态性 形成对比,其中 head 函数始终相同,无论 a.

的类型如何

Is type class the only way to define polymorphic functions?

,见上一节

Can I define == and /= for Bool (and any other type) without using type class Eq?

这取决于所有类型的实现是否相同。您可以使用 -XNoImplicitPrelude 标志来避免导入 Prelude,然后您可以定义自己的 (==) 函数。

您始终可以编写 无约束 多态函数,不需要任何类型class。一个简单的例子是

length :: [a] -> Int

– 这在没有类型class 的情况下有效,并且(好吧,因为)它适用于任何类型 a 随便。也就是说,length 实际上并不关心列表中的 values 是什么,它只关心那些值所在的 structure包含。它实际上从不对这些值本身做任何事情,多态类型实际上保证了这一点。

如果您需要的多态任务是这种形式,即您实际上不需要访问的类型,您只知道它就在那里,那么您不应该write/invoke一个类型class,就像length一样使用ML-style参数多态。但是,您经常 需要自己访问这些值,以某种方式检查它们。这样做而不将您限制为特定的具体类型是类型 classes 的用途。 Eq,正如你自己引用的那样,就是一个例子。