使用 Haskell 列表时,为什么要在 t -> [t] -> [t] 的签名中包含 (Eq t) ?

noe*_*ndo 1 haskell types typeclass

我正在使用使用 t 类型元素列表的函数。这意味着列表可以是整数列表或字符串或字符列表。但我不明白为什么 (Eq t) 必须位于类型签名中。

例如

belong :: (Eq t) => t -> [t] -> Bool    
belong e [] = False
belong e (x:xs) | e == x = True
                | otherwise = belong e xs
Run Code Online (Sandbox Code Playgroud)

--为什么 (Eq t) 出现在签名中?

Ale*_*ell 5

您将列表元素x与项目e,进行比较e == x。这是一个测试这两个类型项t是否相等的操作。要做到这一点,项目本身必须具有可比性,因为你不能只是将两个任意的事物相互比较。您的函数在类型上是参数多态的t,这是一个不受约束的类型变量,因此类型可以是任何类型,并且不可能一般地推理该类型上可能的态射。

函数签名中的类约束(Eq t) =>表明该类型t应该属于 typeclass Eq。它表达了列表中的项目和您要比较的项目必须具有可比性的要求。

class Eq a where
  (==) :: a -> a -> Bool
   ...
Run Code Online (Sandbox Code Playgroud)

Typeclass定义了具有 type 的Eq函数,它就像一个“接口”,所有实现该类型类的类型都将具有该接口。==a -> a -> Bool

==函数的确切实现将根据用于的具体类型的类型类实例确定;它是临时多态性的一个示例,其中每个具体值都采用一个类型类,因为它已为此类型类给出了单独的定义。Eqt