Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two instance of the same type class for the same type

Imagine we have a Haskell program which uses a library. The program provides a typeclass TC instance for a type T from one of its dependencies. In the next version of the same library, the library authors provided another instance of the typeclass TC for type T.

We want to use both of the typeclass instances. How can we do so?

P.S. newtype solution won't work. Both instances reside in libraries which we don't control.

P.P.S. I don't have an example of real code. It's a theoretical question. I just want to learn how type classes work with library composability.

like image 979
Konstantin Solomatov Avatar asked Dec 04 '22 00:12

Konstantin Solomatov


2 Answers

The Haskell 2010 Report §4.3.2 states that

  • A type may not be declared as an instance of a particular class more than once in the program.

So it is not possible in standard Haskell.

I am not aware of any GHC extension that would allow you to do this in GHC.

This is (one?) reason why orphan instances (defining an instance in a different module from both the type and the typeclass) are generally considered a bad idea.

like image 178
dave4420 Avatar answered Jan 08 '23 04:01

dave4420


In general multiple type class instances for the same type isn't possible. However, if a type is defined in a different package, or an older version of the same package, ghc will consider it a different type. So you could in theory have foo-1.1 define Foo and instances for it, and foo-1.2 define Foo and instances for it, and use the two together.

However, in practice this wouldn't work well. Functions will only work with one type or the other. When you write a function that operates on a Foo, it will operate on only one particular Foo, not both of them. Essentially you have two completely separate, incontrovertible types. It would be awkward to use, completely separate from how awkward it will be to build.

like image 20
John L Avatar answered Jan 08 '23 05:01

John L