This question originally arose during my work on a dynamic JS type validator that relies on dictionary passing style as a rather simple type class mechanism, but I think it also applies to Haskell or other languages having a type class mechanism.
At first I figured it wouldn't be too big a problem to allow several type class instances per type in a setting with dictionary passing style, because I have full control of the type class resolution. But the actual issue seems to maintain type safety not type class resolution, as I am going to demonstrate using the type validator. Since the code is type annotated it is language agnostic to some extend.
// please assume `Number` to be a non-polymorphic `Int` type
Sum.Monoid // Monoid<Number>
Prod.Monoid // Monoid<Number>
Function.Monoid // Monoid<b> -> Monoid<(a -> b)>
Function.Monoid(Prod.Monoid) // Monoid<(a -> Number)>
Function.Monoid(Prod.Monoid).append // (a -> Number) -> (a -> Number) -> a -> Number
When you apply these types type safety is compromized, because it is possible to just write the following contrieved expression without the validator complaining:
Function.Monoid(Prod.Monoid)
.append(inc) (inc) (Sum.Monoid.empty); // yields 1 ((0 + 1) * (0 + 1)) instead of 4 ((1 + 1) * (1 + 1))
In Haskell each instance has its own distinct type to prevent such nonsensical expressions. But having to convert from one type-wrapper to another can be tedious.
Is there a viable, type-safe alternative or is this the very reason why Haskell's designers chose the distinct-type-per-class-instance simplification?
In some situations you can safely use a local explicit instance. In Haskell the
reflection
library can be used to create such a local instance. See the Reified Monoids for example.There was also a paper about building that into the language and perhaps making it more usable and general, but I have not read it: Coherent Explicit Dictionary Application for Haskell by Thomas Winant and Dominique Devriese, here is a quote from their contributions section: