我目前正在阅读this,但如果我说实话,我很难看到
class Eq a where
(==) :: a -> a -> Bool
实现,
instance Eq Integer where
x == y = x `integerEq` y
没有实现。我理解第二个代码定义了在两个Integer类型上执行相等的结果应该是什么。第一个的目的是什么呢??
答案 0 :(得分:4)
第一个定义了必须为类型提供哪些操作才能使其具有可比性。然后,您可以使用它来编写在任何类型上运行的函数,这些函数具有可比性,而不仅仅是整数。
allSame :: Eq a => [a] -> Bool
allSame [] = []
allSame (x:xs) = foldr True (==x) xs
此函数适用于整数,因为Eq Integer
的实例存在。它也适用于字符串([Char]
),因为Eq Char
的实例存在,并且实例Eq
的类型列表的实例也存在(instance Eq a => Eq [a]
)。< / p>
答案 1 :(得分:2)
有一个类和许多不同类型的实例。这就是为什么类指定所需的签名(接口;类也可以指定默认实现,但这不是重点),以及实体(实现)。然后使用类名作为约束,这意味着“实现a
操作的任何类型Eq
,即在Eq
”中有一个实例。
阅读Learn you a Haskell或Real World Haskell,它们比haskell.org教程更好。
答案 2 :(得分:2)
class
声明说“我现在将定义一系列功能,这些功能将适用于多种不同的类型”。 instance
声明说“这就是此类型的这些函数的用法”。
在您的具体示例中,class Eq
表示“Eq
表示任何具有名为==
的函数的类型”,而instance Eq Integer
表示“这就是==
1}}适用于Integer
“。
答案 3 :(得分:0)
假设您要实现通用算法或数据结构,“泛型”意味着多态:它应该适用于任何数据类型。例如,假设您要编写一个函数来确定三个输入值是否相等。
采用特定的(单态)情况,你可以对整数执行此操作:
eq3 :: Int -> Int -> Int -> Bool
eq3 x y z = x == y && y == z
我们希望上面的定义也适用于其他类型,当然,如果我们只是告诉编译器该函数应该适用于任何类型:
eq3 :: a -> a -> a -> Bool
eq3 x y z = x == y && y == z
...编译器抱怨==
函数不适用于我们的通用a
:
<interactive>:12:49:
No instance for (Eq a)
arising from a use of `=='
In the first argument of `(&&)', namely `x == y'
In the expression: x == y && y == z
In an equation for `eq3': eq3 x y z = x == y && y == z
我们必须告诉编译器我们的类型a
是Eq
类型类的实例,您已经注意到它是==
函数的位置被宣布。看到这里的区别:
eq3 :: Eq a => a -> a -> a -> Bool
eq3 x y z = x == y && y == z
现在我们有一个函数可以在属于a
类型类的任何类型Eq
上统一运行。