[Haskell-beginners] Idiomatic way to avoid type class instance definitions for Int and Integer separately

Daniel Fischer daniel.is.fischer at googlemail.com
Tue Mar 15 20:58:03 CET 2011


On Tuesday 15 March 2011 20:28:38, aditya siram wrote:
> Untested, but you might try:
> 
> instance (Num t) => YesNo t where  ....

Careful with that. That doesn't work as one expects at first, if you have 
that and try to also have an

instance YesNo Bool where
    yesno = id

you'll get a compiler error.

For instance selection, only the part after the "=>" in

instance (Num t) => YesNo t where ...

is taken into account, so that basically says
"every type [because every type is unifiable with 't'] is an instance of 
YesNo - but if you try to use yesno on a type which is not an instance of 
Num, you'll get a compile error".

You can allow both instance declarations by turning on 
OverlappingInstances, but that's not something to do light-heartedly 
because that opens the way for a number of other problems.

Regarding the original question, that sort of boilerplate is often 
unnecessary because in real programmes, the type of yesno's argument can 
usually be determined from the context, which isn't available at the ghci 
prompt. At the prompt, you could specify the type of the argument directly,

ghci> yesno (10 :: Int)
True

which may be less inconvenient than adding instances to satisfy ghci's 
defaulting algorithm.

Otherwise,
- if you know you don't need any other instances, deech's suggestion is 
great
- if you know that using OverlappingInstances is safe, deech's suggestion 
is great
- if you need other instances and can't/don't want to use 
OverlappingInstances, you can reduce the burden of the boilerplate by using 
preprocessor macros or Template Haskell (the latter is GHC only, so if you 
want portability, it's macros or code generation).



More information about the Beginners mailing list