Search code examples
haskell

Type Eq weirdness in Hashell


Learning how to write typeClasses in haskell

Wrote the following at first

data Trivial = ATrivial
instance Eq Trivial where 
  (==) trVal1 trVal2 = trVal1  == trVal2 

and wonder why it does work?

Indeed the following expression should not compile,

trVal1  == trVal2 

cause == on Trivial is not defined, at best it should recurse indefinitely. Indeed if my understanding of Type classes is correct the only possible type of trVal1 and trVal2 is Trivial. That is constrained by type argument of the Type Class Eq Trivial.

In any case even when I write this, it still works

data Trivial = ATrivial
instance Eq Trivial where 
  (==) trVal1 trVal2 = trVal1 :: Trivial  == trVal2 :: Trivial 

I believe the proper way to write this is:

data Trivial = ATrivial
instance Eq Trivial where 
  (==) ATrivial ATrivial = True  -- Using pattern matching

Am I misunderstanding or not seeing something here ? Can anyone help disambiguating this .....

Edit: upon writing the following in GHCI

ATrivial == ATrivial

I just get nothing back ? Is there a way to get the REPL to complain rather than silently killing the recursion.

In fact no idea what the REPL is doing


Solution

  • It compiles because it's in general perfectly sensible to have recursive definitions, also for class instances. For example, an Eq instance for a list type would look like

    data List a = Nil | Cons a (List a)
    
    instance (Eq a) => Eq (List a) where
      Nil == Nil = True
      Cons h t == Cons h' t' = h==h' && t==t'
      _ == _ = False
    

    Here, t==t' is also a recursive call to the “not yet defined” == operator on List a, but unlike in your example it's called with reduced arguments so this will terminate if called with finite lists.

    Unlike Agda and Coq, Haskell generally doesn't prevent you from writing recursion that just loops forever without progress, again independent of whether you're defining a standalone function or instantiating a class method.