intrigued_66
intrigued_66

Reputation: 17248

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. What is the purpose of the first then??

Upvotes: 3

Views: 1450

Answers (4)

mergeconflict
mergeconflict

Reputation: 8276

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:

<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. 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.

Upvotes: 0

MathematicalOrchid
MathematicalOrchid

Reputation: 62818

The class declaration says "I'm going to define a bunch of functions now which will work for several different types". The instance declaration says "this is how these functions work for this type".

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".

Upvotes: 9

R. Martinho Fernandes
R. Martinho Fernandes

Reputation: 234484

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. 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]).

Upvotes: 4

Cat Plus Plus
Cat Plus Plus

Reputation: 129764

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, i.e. have an instance in Eq".

Read Learn you a Haskell or Real World Haskell, they're better than the haskell.org tutorial.

Upvotes: 2

Related Questions