Search code examples
haskelltypeclasstype-constraints

Can you make an instance of a class not for a type but for a whole class in Haskell?


Suppose I want to make all numbers an instance of Monoid. Instead of having to create an instance for each Num like this:

instance Monoid Int where
  mappend = (+)
  mempty = 0

instance Monoid Float where
  mappend = (+)
  mempty = 0.0

-- etc

Is there something like this?

instance Num t => Monoid t where
  mappend = (+)
  mempty = 0

Edit

Some are answering with GHC extensions and warning about the potential issues; I found that informative, but I think I will stick with Sum, Product and whatever coerce does.


Solution

  • I'm interpreting this as asking about a general premise, rather than specifically about Monoid and Num.

    Maybe you could get what you wrote to work, by enabling language extensions FlexibleInstances, UndecidableInstances, and using overlapping instances.

    But you probably wouldn't want to: it seems like instance Num t => Monoid t where ... is saying

    "If t is an instance of Num, here's how to make t an instance of Monoid..."

    Unfortunately, that's not right. What it's actually saying is more like

    "Here's how to make t an instance of Monoid. First, it's necessary that t be an instance of Num. Next..."

    Thus, if you write an instance declaration like this, you can't write any other instance declarations. (At least not without OverlappingInstances, which would bring its own issues.)