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