Do classes have instances or do data declarations have instances or both?

I’m trying to understand the relationship between data types/declarations, classes and instances.

I’m looking at data Double and class Eq a that I found using Hoogle, and both show the instance Eq Double. However, my understanding is there is only one instance and searching GHC code for “instance Eq Double” only shows up once in libraries/ghc-prim/GHC/Classes.hs.

So I’m wondering if the instance Eq Double is

  • part of class Eq a,
  • part ofdata Double
  • or really neither, perhaps an independent thing that ties the two together.

The language used by books and articles is confusing (maybe conflicting) and uses terms like “inherited” and “member of” so I haven’t been able to get a clear answer.

Also, a side question of interest to me but not really necessary to know, I don’t see in ghc on GutHub the declaration for class Eq a. I did find it in docs under Data.Eq and the uri indicates in is in the ‘base’ package but I don’t see a base package on github.

tl;dr - class has instance, data implements instance

In Haskell, a class is a structure containing named function pointers with partially-restricted types. Any data type can have an instance of any class as long as you can instantiate the partial-restrictions using that data type.

So in your example, there is a class Eq a which contains a function named (==) with partial type restriction (==) :: a -> a -> Bool

The data type Double declares an instance of the Eq class with instance Eq Double.
Then Double provides an implementation of each of the named functions in the class, where the partial restrictions are filled in (wherever there was an ‘a’, it is replaced with ‘Double’). Thus, Eq Double must have a function (==) :: Double -> Double -> Bool.

Many classes also document expected behaviors among the class functions, but these are not currently enforced by the compiler (eg. for all ‘a’, a == a returns True).

3 Likes

Correct. Double is the data; Eq in an interface (defining == and /=); instance Eq Dobule is the instance of Eq for Double, allowing you to use == and /= on values of type Double.

2 Likes

There cam be nullary type classes, with nullary instances. I think those constructions allow us get to the bottom of this :slight_smile: