While trying to understand instances in Haskell I made this example. The Integer part works well but it does not work for the Float instance. I think it is better to make a single instance of the type Num (so that square works on all Num). I suppose I have to add Num as a constraint to my class declaration but I couldn't figure out what the instance would look like. As I understand it, the constraint on the class forces any instances to be of that type (according to the constraint).
class Square a where
area :: a -> a
instance Square Integer where
area a = a*a
instance Square Float where
area a = a*a
I think it is better to make a single instance of the type
Num
...
Not really, unless you want to define that class only for Num
types (and then you don't need a class at all, just make it area :: Num a => a->a
as a top-level function).
Here's the way to make such a generic instance:
instance (Num a) => Square a where
area a = a*a
This is not Haskell98, but it does work with the widely used -XFlexibleInstances
and -XUndecidableInstances
extensions.
Problem: if you then also want to add, say,
instance Square String where
area str = concat $ replicate (length str) str
you have two overlapping instances. And that's a problem: in general, the compiler can't decide which of two such instances is the right one. Again GHC has extensions to make the best guess (-XOverlappingInstances
and -XIncoherentInstances
), but unlike Flexible/UndecidableInstances
these are generally avoided.
Therefore I would recommend making individual instances Square Int
, Square Integer
, Square Double
. They're not, like, hard to write, are they?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With