Why is it that the following code:
class TheClass (t :: * -> * -> *)
where
type TheFamily t :: * -> Constraint
data Dict (c :: Constraint)
where
Dict :: c => Dict c
foo :: forall t a b.
( TheClass t
, (forall x y. (TheFamily t x, TheFamily t y) => TheFamily t (t x y))
, TheFamily t a
, TheFamily t b
) => Dict (TheFamily t (t a b))
foo = Dict
-- NB: Only using `Dict` to assert that the relevant constraint is satisfied in the body of `foo`
produces the error:
• Could not deduce: TheFamily t (t a b)
arising from a use of ‘Dict’
from the context: (TheClass t,
forall x y. (TheFamily t x, TheFamily t y) => TheFamily t (t x y),
TheFamily t a, TheFamily t b)
bound by the type signature for:
foo :: forall (t :: * -> * -> *) a b.
(TheClass t,
forall x y. (TheFamily t x, TheFamily t y) => TheFamily t (t x y),
TheFamily t a, TheFamily t b) =>
Dict (TheFamily t (t a b))
but the following seemingly trivial modification to foo
:
foo' :: forall t a b temp.
( TheClass t
, TheFamily t ~ temp
, (forall x y. (temp x, temp y) => temp (t x y))
, TheFamily t a
, TheFamily t b
) => Dict (TheFamily t (t a b))
foo' = Dict
makes the compiler happy?
Shouldn't the two snippets be equivalent? All I'm doing is aliasing TheFamily t
as some other temporary type variable using an equality constraint.
forall x y. (TheFamily t x, TheFamily t y) => TheFamily t (t x y)
isn't allowed in the first place, so it doesn't matter that it doesn't work properly. GHC 8.10.1 complains "Quantified predicate must have a class or type variable head". Your GHC seems to lack this check. I'm voting to close. – Aerologyfoo
with that error but acceptsfoo'
. – Dividivi