Unifying inferred and declared *existential* type variables
Dr. ERDI Gergo
gergo at erdi.hu
Sat Aug 16 08:29:14 UTC 2014
Hi,
Background:
Type signatures for pattern synonyms are / can be explicit about the
existentially-bound type variables of the pattern. For example, given the
following definitions:
data T where
C :: (Eq a) => [a] -> (a, Bool) -> T
pattern P x y = C x y
the inferred type of P (with explicit foralls printed) is
pattern type forall a. Eq a => P [a] (a, Bool) :: T
My problem:
Ticket #8968 is a good example of a situation where we need this
pattern type signature to be entered by the user. So continuing with the
previous example, the user should be able to write, e.g.
pattern type forall b. Eq b => P [b] (b, Bool) : T
So in this case, I have to unify the argument types [b] ~ [a] and (b,
Bool) ~ (a, Bool), and then use the resulting coercions of the
existentially-bound variables before calling the success continuation.
So I generate a pattern synonym matcher as such (going with the previous
example) (I've pushed my code to wip/T8584):
$mP{v r0} :: forall t [sk].
T
-> (forall b [sk]. Eq b [sk] => [b [sk]] -> (b [sk], Bool) -> t [sk])
-> t [sk]
-> t [sk]
$mP{v r0}
= /\(@ t [sk]).
\ ((scrut [lid] :: T))
((cont [lid] :: forall b [sk]. Eq b [sk] => [b [sk]] -> (b [sk], Bool) -> t [sk]))
((fail [lid] :: t [sk]))
-> case scrut
of {
C {@ a [ssk] ($dEq_aCt [lid] :: Eq a [ssk]) EvBindsVar<aCu>}
(x [lid] :: [a [ssk]])
(y [lid] :: (a [ssk], Bool))
-> cont b $dEq_aCr x y
|> (cobox{v} [lid], <Bool>_N)_N
|> [cobox{v} [lid]]_N }
<>}
The two 'cobox'es are the results of unifyType'ing [a] with [b] and (a,
Bool) with (b, Bool). So basically what I hoped to do was to pattern-match
on 'C{@ a $dEqA} x y' and pass that to cont as 'b' and '$dEqB' by
rewriting them with the coercions. (It's unfortunate that even with full
-dppr-debug output, I can't see what's inside the 'cobox'es).
However, when I try doing this, I end up with the error message
SigGADT2.hs:10:9:
Couldn't match type ‘a [ssk]’ with ‘b [sk]’
because type variable ‘b [sk]’ would escape its scope
This (rigid, skolem) type variable is bound by
the type signature for
P :: [b [sk]] -> (b [sk], Bool) -> T
at SigGADT2.hs:10:9
Expected type: [b [sk]]
Actual type: [a [ssk]]
Also, while the result of unifying '[b]' ~ '[a]' and '(b, Bool)' ~
'(a, Bool)' should take care of turning the 'a' bound by the constructor
into the 'b' expected by the continuation function, it seems to me I'll
need to do some extra magic to also turn the bound 'Eq a' evidence
variable into the 'Eq b'.
Obviously, I am missing a ton of stuff here. Can someone help me out?
Thanks,
Gergo
--
.--= ULLA! =-----------------.
\ http://gergo.erdi.hu \
`---= gergo at erdi.hu =-------'
I love vegetarians - some of my favorite foods are vegetarians.
More information about the ghc-devs
mailing list