[GHC] #16344: GHC infers over-polymorphic kinds
GHC
ghc-devs at haskell.org
Wed Feb 20 11:06:16 UTC 2019
#16344: GHC infers over-polymorphic kinds
-------------------------------------+-------------------------------------
Reporter: simonpj | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 8.6.3
Keywords: | Operating System: Unknown/Multiple
Architecture: | Type of failure: None/Unknown
Unknown/Multiple |
Test Case: | Blocked By:
Blocking: | Related Tickets:
Differential Rev(s): | Wiki Page:
-------------------------------------+-------------------------------------
Consider
{{{
data T ka (a::ka) b = MkT (T Type Int Bool)
(T (Type -> Type) Maybe Bool)
}}}
GHC accepts this ''even though it uses polymorphic recursion''. But it
shouldn't -- we simply do not have reliable way to infer most general
types in the presence of polymorphic recursion.
In more detail, in `getInitialKinds`, GHC chooses this (bogus)
"monomorphic" kind for T:
{{{
T :: forall (ka :: kappa1) -> ak -> kappa2 -> Type
}}}
where `kappa1` and `kappa1` are unification variables. Then it kind-
checks the data constructor declaration, given this mono-kind -- and
succeeds!
But this is extremely fragile. At call-sites of T we are going to
instantiate T's kind. But what if `kappa2` is
(somewhere, somehow) late unified wtih `ka`. Then, when instantiating T's
kind with `ka := blah`we should get
`blah -> blha -> Type`. So how it instantiates will vary depending on
what we konw about `kappa2`.
No no no. The initial monomorphic kind of T (returned by
`getInitialKinds`, and used when checking the recursive RHSs)
should be
{{{
T :: kappa1 -> kappa2 -> kappa3 -> Type
}}}
Then indeed this program will be rejected, but so be it.
Consider
{{{
data T ka (a::ka) b = MkT (T Type Int Bool)
(T (Type -> Type) Maybe Bool)
}}}
GHC accepts this ''even though it uses polymorphic recursion''. But it
shouldn't -- we simply do not have reliable way to infer most general
types in the presence of polymorphic recursion.
In more detail, in `getInitialKinds`, GHC decides this "monomorphic" kind
for T:
{{{
T :: forall (ka :: kappa1) -> ka -> kappa2 -> Type
}}}
where `kappa1` and `kappa1` are unification variables. Then it kind-
checks the data constructor declaration, given this mono-kind -- and
succeeds!
But this is extremely fragile. At call-sites of T we are going to
instantiate T's kind. But what if `kappa2` is
(somewhere, somehow) late unified wtih `ka`. Then, when instantiating T's
kind with `ka := blah` we might get
`blah -> blah -> Type` or `blah -> kappa2 -> Type`, depending on whether
`kappa2 := ka` has happened yet.
No no no. The initial monomorphic kind of T (returned by
`getInitialKinds`, and used when checking the recursive RHSs)
should be
{{{
T :: kappa1 -> kappa2 -> kappa3 -> Type
}}}
Then indeed this program will be rejected, but so be it.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/16344>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list