I have code that compiles:
{-# LANGUAGE ScopedTypeVariables, KindSignatures, GADTs, FlexibleContexts #-} module Foo where data Foo :: (* -> *) where Foo :: cm zp' -> Foo (cm zp) f :: forall cm zp d . Foo (cm zp) -> d f y@ (Foo (x :: cma)) = gxy g :: cma -> Foo (cmb) -> d g = error ""
The key point in my real code is to convince the GHC that if y is of type Foo (cm zp) and x is of type c' m' zp' , then c' ~ c and m' ~ m . The above code achieves this because I can call g .
I want to change this code in two orthogonal ways, but I cannot figure out how to get GHC to compile the code with any change.
First change: Add -XPolyKinds . GHC 7.8.3 complains:
Foo.hs:10:11: Could not deduce ((~) (k2 -> k3 -> *) c1 c) from the context ((~) * (cm zp) (c1 m1 zp1)) bound by a pattern with constructor Foo :: forall (k :: BOX) (k :: BOX) (c :: k -> k -> *) (m :: k) (zp' :: k) (zp :: k). cm zp' -> Foo (cm zp), in an equation for 'f' at Foo.hs:10:6-21 'c1' is a rigid type variable bound by a pattern with constructor Foo :: forall (k :: BOX) (k :: BOX) (c :: k -> k -> *) (m :: k) (zp' :: k) (zp :: k). cm zp' -> Foo (cm zp), in an equation for 'f' at Foo.hs:10:6 'c' is a rigid type variable bound by the type signature for f :: Foo (cm zp) -> d at Foo.hs:9:13 Expected type: c1 m1 zp' Actual type: cma Relevant bindings include y :: Foo (cm zp) (bound at Foo.hs:10:3) f :: Foo (cm zp) -> d (bound at Foo.hs:10:1) In the pattern: x :: cma In the pattern: Foo (x :: cma) In an equation for 'f': f y@ (Foo (x :: cma)) = gxy Foo.hs:10:11: Could not deduce ((~) k2 m1 m) from the context ((~) * (cm zp) (c1 m1 zp1)) ...
Second change: Forget about -XPolyKinds . Instead, I want to use -XDataKinds to create a new type and restriction of type m :
{-# LANGUAGE ScopedTypeVariables, KindSignatures, GADTs, FlexibleContexts, DataKinds #-} module Foo where data Bar data Foo :: (* -> *) where Foo :: c (m :: Bar) zp' -> Foo (cm zp) f :: forall cm zp d . Foo (cm zp) -> d f y@ (Foo (x :: cma)) = gxy g :: cma -> Foo (cmb) -> d g = error ""
I get similar errors ( can't deduce (c1 ~ c) , can't deduce (m1 ~ m) ). DataKinds seems relevant here: if I restrict m to have a Constraint look instead of a kind Bar , the code compiles fine.
I gave two examples of how to break the source code, both of which use higher-grade types. I tried using case arguments instead of template protection, I tried giving node type instead of x , my usual tricks here do not work.
I donβt understand where the type for x / ends, how it looks, I just need to convince GHC that if y is of type Foo (cm zp) , then x is of type cm zp' for some unrelated type zp' .