[commit: ghc] ghc-8.0: Clarify Note [Kind coercions in Unify] (f260738)

git at git.haskell.org git at git.haskell.org
Mon Mar 28 11:37:27 UTC 2016


Repository : ssh://git@git.haskell.org/ghc

On branch  : ghc-8.0
Link       : http://ghc.haskell.org/trac/ghc/changeset/f260738db2937814757bc27851dcd4d8d3e93296/ghc

>---------------------------------------------------------------

commit f260738db2937814757bc27851dcd4d8d3e93296
Author: Richard Eisenberg <eir at cis.upenn.edu>
Date:   Fri Mar 25 17:25:25 2016 -0400

    Clarify Note [Kind coercions in Unify]
    
    (cherry picked from commit 9f73e46c0f34b8b5e8318e6b488b7dade7db68e3)


>---------------------------------------------------------------

f260738db2937814757bc27851dcd4d8d3e93296
 compiler/types/Unify.hs | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/compiler/types/Unify.hs b/compiler/types/Unify.hs
index bc53cac..76d3ec2 100644
--- a/compiler/types/Unify.hs
+++ b/compiler/types/Unify.hs
@@ -82,10 +82,31 @@ may look nothing alike.
 
 So, we pass a kind coercion to the match/unify worker. This coercion witnesses
 the equality between the substed kind of the left-hand type and the substed
-kind of the right-hand type. To get this coercion, we first have to match/unify
+kind of the right-hand type. Note that we do not unify kinds at the leaves
+(as we did previously). We thus have
+
+INVARIANT: In the call
+    unify_ty ty1 ty2 kco
+it must be that subst(kco) :: subst(kind(ty1)) ~N subst(kind(ty2)), where
+`subst` is the ambient substitution in the UM monad.
+
+To get this coercion, we first have to match/unify
 the kinds before looking at the types. Happily, we need look only one level
 up, as all kinds are guaranteed to have kind *.
 
+When we're working with type applications (either TyConApp or AppTy) we
+need to worry about establishing INVARIANT, as the kinds of the function
+& arguments aren't (necessarily) included in the kind of the result.
+When unifying two TyConApps, this is easy, because the two TyCons are
+the same. Their kinds are thus the same. As long as we unify left-to-right,
+we'll be sure to unify types' kinds before the types themselves. (For example,
+think about Proxy :: forall k. k -> *. Unifying the first args matches up
+the kinds of the second args.)
+
+For AppTy, we must unify the kinds of the functions, but once these are
+unified, we can continue unifying arguments without worrying further about
+kinds.
+
 We thought, at one point, that this was all unnecessary: why should casts
 be in types in the first place? But they do. In
 dependent/should_compile/KindEqualities2, we see, for example
@@ -766,6 +787,7 @@ unify_ty_app ty1 ty1args ty2 ty2args
   | otherwise
   = do { let ki1 = typeKind ty1
              ki2 = typeKind ty2
+           -- See Note [Kind coercions in Unify]
        ; unify_ty ki1 ki2 (mkNomReflCo liftedTypeKind)
        ; unify_ty ty1 ty2 (mkNomReflCo ki1)
        ; unify_tys ty1args ty2args }
@@ -776,6 +798,7 @@ unify_tys orig_xs orig_ys
   where
     go []     []     = return ()
     go (x:xs) (y:ys)
+      -- See Note [Kind coercions in Unify]
       = do { unify_ty x y (mkNomReflCo $ typeKind x)
            ; go xs ys }
     go _ _ = maybeApart  -- See Note [Lists of different lengths are MaybeApart]



More information about the ghc-commits mailing list