Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 676
Lay González Avatar asked Sep 24 '15 19:09

Lay González


People also ask

What is a Typeclass in Haskell?

What's a typeclass in Haskell? A typeclass defines a set of methods that is shared across multiple types. For a type to belong to a typeclass, it needs to implement the methods of that typeclass. These implementations are ad-hoc: methods can have different implementations for different types.

Does Haskell have inheritance?

Does Haskell have inheritance? Well, no, it doesn't, because Haskell does not have objects, and inheritance is a relationship between two objects. Objects are a combination of internal state (data) and methods (behavior).

What is instance Haskell?

An instance of a class is an individual object which belongs to that class. In Haskell, the class system is (roughly speaking) a way to group similar types. (This is the reason we call them "type classes"). An instance of a class is an individual type which belongs to that class.

What is deriving Show in Haskell?

The second line, deriving (Eq, Show) , is called the deriving clause; it specifies that we want the compiler to automatically generate instances of the Eq and Show classes for our Pair type. The Haskell Report defines a handful of classes for which instances can be automatically generated.


1 Answers

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.)

like image 173
Michael Benfield Avatar answered Oct 20 '22 18:10

Michael Benfield