I am running into a problem where GHC is not able to match Foo t and Foo t0, where it definitely looks to me like t ~ t0. Here's a minimal example:
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeFamilies #-}
data Foobar :: * -> * where
Foobar :: Foo t -> Foobar t
type family Foo a :: *
class Bar t where
f :: Foobar t
g :: Foo t
-- f = Foobar g
When uncommenting the last line, GHC complains:
Couldn't match expected type ‘Foo t’ with actual type ‘Foo t0’
NB: ‘Foo’ is a type function, and may not be injective
The type variable ‘t0’ is ambiguous
Relevant bindings include f :: Foobar t (bound at test.hs:13:3)
In the first argument of ‘Foobar’, namely ‘g’
In the expression: Foobar g
I understand that Foo is not injective, but from my analysis GHC is never asked to come up with t from Foo t. It seems that the type t is lost in Foobar g, and so it can't match the inital Foo t and the new Foo t0. Is the context here not enough? Am I missing a case where f = Foobar g could not yield the correct result?
Any help appreciated!
N.B.: ScopedTypeVariables and explicit type signatures don't seem to help. Adding the constraint a ~ Foo t and using a instead as the type of g in Foobar g doesn't work either.
Looks a lot like: ambiguous type error when using type families, and STV is not helping. I considered using a Proxy, but I feel like in this case GHC should be able to figure it out.