Issue with overlapping instances

The issue is that there are some hidden kind variables in play. You can fix it by giving Embeds an explicit kind signature:

import Data.Kind

type Embeds :: (Type -> Type) -> (Type -> Type) -> Constraint
class Embeds m n where
-- ...

Or alternatively, give the type variable a an explicit type:

class Embeds m n where
  embed :: forall (a :: Type). m a -> n a

(Or alternatively, alternatively, you could use NoPolyKinds)

I discovered this by trying to minimize your reproducer, but next time you can try adding -fprint-explicit-kinds. Then the error message becomes as follows:

Main.hs:46:3: error: [GHC-43085]
    • Overlapping instances for Embeds
                                  @{*} (StateT Int Identity) (StateT Int IO)
        arising from a use of ‘embed’
      Matching instances:
        instance [overlapping] forall k (n :: * -> *)
                                      (t :: (* -> *) -> k -> *) (m :: * -> *).
                               (Monad n, MFunctor @{k} t, Embeds @{*} n m) =>
                               Embeds @{k} (t n) (t m)
          -- Defined at Main.hs:33:30
        instance [overlappable] (Monad m, MonadTrans t, Embeds @{*} n m) =>
                                Embeds @{*} n (t m)
          -- Defined at Main.hs:28:31
      An overlapping instance can only be chosen when it is strictly more specific.
      The first instance that follows overlaps the second, but is not more specific than it:
        instance [overlapping] forall k (n :: * -> *)
                                      (t :: (* -> *) -> k -> *) (m :: * -> *).
                               (Monad n, MFunctor @{k} t, Embeds @{*} n m) =>
                               Embeds @{k} (t n) (t m)
        instance [overlappable] (Monad m, MonadTrans t, Embeds @{*} n m) =>
                                Embeds @{*} n (t m)
   |
46 |   embed statefulOperation
   |   ^^^^^

As you can see, while the t n is more specific than n, the kind k is actually more general than *.

5 Likes