简体   繁体   English

类和实例声明之间有什么区别?

[英]What is the differences between class and instance declarations?

I am currently reading this , but if I am honest I am struggling to see what 我目前正在阅读此书 ,但老实说,我正在努力查看

class Eq a where 
  (==)                  :: a -> a -> Bool

achieves, which 实现,

instance Eq Integer where 
  x == y                =  x `integerEq` y

doesnt achieve. 没有实现。 I understand the second code defines what the result of performing equality on two Integer types should be. 我了解第二个代码定义了对两种Integer类型执行相等运算的结果。 What is the purpose of the first then?? 那么第一个目的是什么?

The first defines what operations must be provided for a type to be comparable for equality. 第一个定义了必须提供什么操作才能使类型具有相等性以实现相等性。 You can then use that to write functions that operate on any type that is comparable for equality, not just integers. 然后,您可以使用它来编写可在等于相等性的任何类型上操作的函数,而不仅仅是整数。

allSame :: Eq a => [a] -> Bool
allSame [] = []
allSame (x:xs) = foldr True (==x) xs

This function works for integers because instances for Eq Integer exists. 此函数适用于整数,因为存在Eq Integer实例。 It also works for strings ( [Char] ) because an instance for Eq Char exists, and an instance for lists of types that have instances of Eq also exists ( instance Eq a => Eq [a] ). 它也适用于字符串( [Char] ),因为存在Eq Char的实例,并且还存在具有Eq实例的类型列表的实例( instance Eq a => Eq [a] )。

The class declaration says "I'm going to define a bunch of functions now which will work for several different types". class声明说:“我现在将定义一堆将对几种不同类型起作用的函数”。 The instance declaration says "this is how these functions work for this type". instance声明说:“这就是这些函数在类型下的工作方式”。

In your specific example, class Eq says that " Eq means any type that has a function named == ", whereas the instance Eq Integer says "this is how == works for an Integer ". 在您的特定示例中, class Eq表示“ Eq表示具有名为==的函数的任何类型,而instance Eq Integer表示“这是==Integer ”。

There is one class and many instances for different types. 对于不同类型,有一个类和许多实例。 That's why the class specifies the required signature (interface; classes can also specify default implementations, but that's beside the point), and instance the body (implementation). 这就是为什么该类指定所需的签名(接口;类也可以指定默认实现,但这并不重要),并指定主体(实现)。 You then use class name as a constraint that means "any type a that implements Eq operations, ie have an instance in Eq ". 然后,将类名用作约束,表示“实现Eq操作的任何类型a ,即在Eq具有实例”。

Read Learn you a Haskell or Real World Haskell , they're better than the haskell.org tutorial. 阅读了解您的Haskell真实世界的Haskell ,它们比haskell.org教程要好。

Let's say you want to implement a generic algorithm or data structure, "generic" meaning polymorphic: it should work for any data type. 假设您要实现一个通用算法或数据结构,“通用”表示多态:它适用于任何数据类型。 For example, let's say you want to write a function that determines whether three input values are equal. 例如,假设您要编写一个确定三个输入值是否相等的函数。

Taking a specific (monomorphic) case, you can do this for integers: 考虑特定(单态)情况,您可以对整数执行以下操作:

eq3 :: Int -> Int -> Int -> Bool
eq3 x y z = x == y && y == z

We'd expect the above definition to work for other types as well, of course, but if we simply tell the compiler that the function should apply to any type: 当然,我们希望上面的定义也适用于其他类型,但是如果我们只是简单地告诉编译器该函数应适用于任何类型,则:

eq3 :: a -> a -> a -> Bool
eq3 x y z = x == y && y == z

... the compiler complains that the == function doesn't apply to our generic a : ...编译器抱怨==函数不适用于我们的泛型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

We have to tell the compiler that our type a is an instance of the Eq type class, which you already noticed is where the == function is declared. 我们必须告诉编译器,我们的类型aEq类型类的实例 ,您已经注意到,在其中==函数被声明。 See the difference here: 在这里看到区别:

eq3 :: Eq a => a -> a -> a -> Bool
eq3 x y z = x == y && y == z

Now we have a function that can operate uniformly on any type a belonging to the Eq type class. 现在,我们有了一个函数,可以对属于Eq类型类的任何类型a进行统一操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM