I am quite new to Haskell/Purescript and currently learning by studying the PureScript by Example book.
In chapter 6 about type classes, exercise 4 has following task:
Here is my attempt:(Medium) Given any type
a
with an instance ofOrd
, we can add a new "infinite" value which is greater than any other value:data Extended a = Finite a | Infinite
Write an
Ord
instance forExtended a
which reuses theOrd
instance fora
.
instance ordExtended :: Ord a => Ord (Extended a) where
compare Infinite Infinite = EQ
compare Infinite _ = GT
compare _ Infinite = LT
compare (Finite f1) (Finite f2) = compare f1 f2
Unfortunately, the code triggers an error:
No type class instance was found for
Data.Eq.Eq (Extended a0)
while checking that expression #dict Eq has type { eq :: Extended a0 -> Extended a0 -> Boolean } in value declaration ordExtended
where a0 is a rigid type variable bound at (line 0, column 0 - line 0, column 0) PureScript(NoInstanceFound)
I cannot quite understand the error message:
expression #dict Eq
mean? There is no dict
in my code.a0
(why? I assume, that is a
)In my book, Eq
type class instance should be covered by implementing Ord
, as Ord
extends Eq
.
The key part of the error is at the start:
No type class instance was found for
Data.Eq.Eq (Extended a0)
Here is the definition of Ord
:
class Eq a <= Ord a where
compare :: a -> a -> Ordering
This is actually the superclass syntax, saying that you need an Eq
instance to have an Ord
instance. So, you can fix the error by making an Eq
instance:
instance eqExtended :: Eq a => Eq (Extended a) where
eq Infinite Infinite = true
eq (Finite f1) (Finite f2) = eq f1 f2
eq _ _ = false
instance ordExtended :: Ord a => Ord (Extended a) where
compare Infinite Infinite = EQ
compare Infinite _ = GT
compare _ Infinite = LT
compare (Finite f1) (Finite f2) = compare f1 f2
As to why a0
is used, it seems the purescript compiler just likes adding numbers after type variables, possibly to reduce vagueness or to allow for scoped type variables. You can read about rigid type variables here (they're basically variables that can't be changed to fit constraints).