I have the following code. Class1
instances say what the direct superclass is of a class, SuperClass1
automatically traverses Class1
to find all superclasses. (I have omitted the actual methods of these classes because they are not relevant for my issue.)
{-# LANGUAGE PolyKinds, RankNTypes, ConstraintKinds, FlexibleInstances, UndecidableInstances, MultiParamTypeClasses, FunctionalDependencies #-}
class Class1 b h | h -> b
instance Class1 Functor Applicative
instance Class1 Applicative Monad
class SuperClass1 b h
instance {-# OVERLAPPING #-} SuperClass1 b b
instance {-# OVERLAPPABLE #-} (SuperClass1 b c, Class1 c h) => SuperClass1 b h
This works great! Now I want to use it like this:
newtype HFree c f a = HFree { runHFree :: forall g. c g => (forall b. f b -> g b) -> g a }
instance SuperClass1 Functor c => Functor (HFree c f)
instance SuperClass1 Applicative c => Applicative (HFree c f)
instance SuperClass1 Monad c => Monad (HFree c f)
test :: (a -> b) -> HFree Monad f a -> HFree Monad f b
test = fmap
(I.e. I can give an instance of Functor
for Hfree c f
whenever Functor
is a superclass of c
.)
And this gives this error in the Applicative instance (and similar for the Monad instance):
• Overlapping instances for SuperClass1 Functor c1
arising from the superclasses of an instance declaration
Matching instances:
instance [overlappable] forall k k k (b :: k) (c :: k) (h :: k).
(SuperClass1 b c, Class1 c h) =>
SuperClass1 b h
-- Defined at superclass.hs:17:31
instance [overlapping] forall k (b :: k). SuperClass1 b b
-- Defined at superclass.hs:16:30
(The choice depends on the instantiation of ‘c1, k1’
To pick the first instance above, use IncoherentInstances
when compiling the other instance declarations)
• In the instance declaration for ‘Applicative (HFree c f)’
As far as I understand, what happens is that an Applicative instance requires a Functor instance, so the Applicative instance also needs the SuperClass1 Functor c
constraint from Functor. And indeed if I add this, the error goes away. (This is what I currently have: http://hackage.haskell.org/package/free-functors-0.7/docs/Data-Functor-HFree.html)
But somehow GHC is smart enough to understand that SuperClass1 Applicative c
implies SuperClass1 Functor c
, because it doesn't complain about a missing constraint. Instead it gets stuck on an overlapping instances error. It would be great if there's a way to fix the error, but I can't figure out how!
test
- theMonad
andApplicative
instances fail with an overlap error, because your instances are overlapping very badly. The only constraint of the formSuperClass1 a b
that the compiler will be able to solve here isSuperClass1 a a
- that is, when the types are a-priori known to be the same. In all other cases, it will give you an error. (also note, GHC doesn't even know thatSuperClass1 Functor c
impliesFunctor
whenc
holds - as far as it is concerned,SuperClass1
actually contains no information) – user2407038(SuperClass1 b c, Class1 c h) => SuperClass1 b h
should be(Class1 c h, SuperClass1 b c) => SuperClass1 b h
. See if this changes anything. Shooting in the dark here. :) – Will Ness