Two instances of the same type for the same type

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

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

PS the new solution will not work. Both instances are in libraries that we do not control.

PPS I have no real code example. This is a theoretical question. I just want to know how type classes work with a library.

+4
source share
5 answers

The Haskell 2010 Report Β§4.3.2 states that

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

So this is not possible in standard Haskell.

I don't know the GHC extension that will allow you to do this in the GHC.

This (one?) Is the reason why orphans (defining an instance in another module from both a type and a class) are usually considered bad.

+5
source

In the general case, instances of a class of several types for the same type are impossible. However, if the type is defined in another package or in an old version of the same package, ghc will consider it a different type. Thus, theoretically, one could foo-1.1 define Foo and instances for it, and foo-1.2 define Foo and instances for it and use them together.

However, in practice this will not work. Functions will work with only one type or another. When you write a function that works with Foo , it will only work with one specific Foo , not both of them. Essentially, you have two completely different, irrefutable types. It would be inconvenient to use, completely separate from how inconvenient to build.

+4
source

I can safely say that with Cabal, you can depend on only one version of the same library.

Although it’s possible for you to at least copy-paste the source code of an alternative version of the instance into your project, you can still import only one of them for each module. If you import conflicting instances into a module, you will run into the problem of unsolvable instances for which you will not have a practical solution.

To tell you the truth, I can’t imagine why you need to have different instances of the same class for the same type released by the same library. This seems extremely impractical. Although my guess about what can help you in your situation is to have two types with the appropriate instances: one from the current version of the library, the other a renamed copy of the source code of the older version.

+3
source

If you need a more flexible and convenient layout, re-enter the class types as an entry. RankNTypes may be required.

For example, here, as you could confirm the Applicative type class

 {-# LANGUAGE RankNTypes #-} data ApplicativeInstance f = ApplicativeInstance { pure :: forall a. a -> fa , amap :: forall a b. (a -> b) -> fa -> fb , ap :: forall a b. f (a -> b) -> fa -> fb } listApplicative = ApplicativeInstance { pure = \a -> [a] , amap = map , ap = \fs xs -> case fs of [] -> [] f:fs' -> map f xs ++ ap cartesianListApplicative fs' xs } zipListApplicative = ApplicativeInstance { pure = \a -> [a] , amap = map , ap = \fs xs -> case (fs, xs) of ([], _) -> [] (_, []) -> [] (f:fs', x:xs') -> fx : ap zipListApplicative fs' xs' } 

Now we get the opportunity to specify which instance we want. However, we lose the ability to implicitly select an instance: now the choice should be explicit.

 ghci> ap listApplicative [(+1), (*3)] [1 .. 5] [2,3,4,5,6,3,6,9,12,15] ghci> ap zip zip zipListApplicative zipWith3 zip3 zipWith ghci> ap zipListApplicative [(+1), (*3)] [1 .. 5] [2,6] 

See also: http://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/

+3
source

Linking with different versions of the same package in the dependency tree is not yet possible because it leads to a dependency conflict.

But it will be possible in the future, as indicated in this GHC status video update , if they are used in only one version in what I think.

+2
source

All Articles