I’ve been reading about the theoretical underpinnings of deep skolemization and simplified subsumption, with Practical Type Inference for Arbitrary-Rank Types and GHC Proposal 0287 as references.
The linked section of the proposal was initially confusing to me: with the definitions
f = undefined
g f = f `seq` 0
we expect g f
to diverge, and it does. However, when we supply the type annotations
f :: forall a b. a -> b -> b
f = undefined
g :: (forall p. p -> (forall q. q -> q)) -> Int
g f = f `seq` 0
g f
evaluates to 0
, as the proposal says. These are not the types inferred in the first example, of course, but it was surprising to me that the static types would affect how f
is evaluated to WHNF at runtime. (The behavior of g (\x y -> f x y)
is unsurprising; as usual, seq
breaks eta-equivalence.)
@jackdk suggested on IRC that with deep skolemization, f
was implicitly getting eta-expanded. I buy that - it’s probably why the proposal emphasizes manual eta-expansion - but that left me wondering if this is actually a requirement of deep skolemization or simply an implementation detail.
In other words, can the definition of subsumption be enriched with deep skolemization (thereby admitting additional desired programs) purely at the type level without requiring implicit eta-expansion at the term level? The typing rules are syntax-directed, of course, but in Fig. 7, it seems that the subsumption relation is enriched via rules directed purely by type-level syntax.