I have to define a type class Truthy
which contains a method true
converting an instance of the type class to a Bool
value.
My type
This might not help for homework, but you actually can write a declaration like that. You just have to enable -XFlexibleInstances
to do so. At least in GHC, you can do this by putting a pragma at the top of your file:
{-# LANGUAGE FlexibleInstances #-}
If you look closely at the error message you got, it said something like "Use -XFlexibleInstances if you want to disable this.".
In this particular case, you would also need to enable UndecidableInstances
and OverlappingInstances
:
{-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances #-}
You need FlexibleInstances
because standard Haskell does not allow instances in any form where the type variable appears more than once in the head. This is completely fine--I it is one of the most common extensions used (as per this question).
You need UndecidableInstances
because your instance declaration could potentially cause the type checker to loop forever. I think using UndecidableInstances
prevents this by limiting how deeply it will check when trying to reduce the instance. This is usually--including in this case--fine, but could theoretically make whether a particular program passes the type checks implementation dependent. Still, it should work in your case.
As hammar pointed out, you need to enable OverlappingInstances
because the "context" of the instance is ignored when checking whether they overlap. The context is the Num a
bit in this case. So the instances--for checking if it overlaps--is read as instance Truthy a...
and overlaps with everything. With OverlappingInstances
enabled, you just need to have one instance that is the most specific for this to work.