Is polykinded type application injective?

前端 未结 2 720
终归单人心
终归单人心 2021-01-12 09:05

Is polykinded type application injective?

When we enable PolyKinds, do we know that f a ~ g b implies f ~ g and a ~ b?

2条回答
  •  陌清茗
    陌清茗 (楼主)
    2021-01-12 10:00

    Polykinded type application is injective from the outside, but certainly not injective from inside Haskell.

    By "injective from the outside" I mean that whenever there is a Refl with type f a :~: g b, then it must be the case that f is equal to g and a is equal to b, and since we know that types of different kinds are never equal, the kinds must be also the same.

    The issue is that GHC only has homogeneous type equality constraints, and doesn't have kind equality constraints at all. The machinery for encoding GADTs using coercions exists only on the type and promoted type level. That's why we can't express heterogeneous equality, and why we can't promote GADTs.

    {-# LANGUAGE PolyKinds, GADTs, TypeOperators #-}
    
    data HEq (a :: i) (b :: k) :: * where
      HRefl :: HEq a a
    -- ERROR: Data constructor ‘HRefl’ cannot be GADT-like in its *kind* arguments 
    

    Also, here's a simple example of GHC not inferring injectivity:

    sym1 :: forall f g a b. f a :~: g b -> g b :~: f a
    sym1 Refl = Refl
    -- ERROR: could not deduce (g ~ f), could not deduce (b ~ a)
    

    If we annotate a and b with the same kind, it checks out.

    This paper talks about the above limitations and how they could be eliminated in GHC (they describe a system with unified kind/type coercions and heterogeneous equality constraints).

提交回复
热议问题