[GHC] #11715: Constraint vs *
GHC
ghc-devs at haskell.org
Thu Feb 9 03:29:34 UTC 2017
#11715: Constraint vs *
-------------------------------------+-------------------------------------
Reporter: bgamari | Owner: goldfire
Type: bug | Status: new
Priority: highest | Milestone: 8.4.1
Component: Compiler (Type | Version: 8.0.1-rc1
checker) | Keywords: Typeable,
Resolution: | LevityPolymorphism
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by goldfire):
As comment:63 says, this patch (available on the `wip/t11715` branch) is
in limbo.
What's the challenge? See
[https://phabricator.haskell.org/D2038#inline-25457 this comment] on a
related patch. The short version is that the design in comment:47 and in
the [https://github.com/ghc-proposals/ghc-proposals/pull/32 ghc-proposal]
require weakening `KindCo` to work only on nominal coercions. And
Phab:D2038 requires it to work on representational ones. The decision was
to punt on this patch in favor of that one.
There is a somewhat-detailed plan of how to proceed, originally posted
[https://mail.haskell.org/pipermail/ghc-devs/2017-February/013702.html
here]:
1. Hold off on Constraint v Type until after the branch is cut.
2. Do what we can to mitigate Constraint v Type confusion vis-a-vis
Typeable. (For example, make sure that there aren't Typeable instances for
both, and have TcTypeable provide the Type instance whenever the
Constraint instance is requested.)
3. Advertise that GHC will be a little confused on this point, and that,
as far as Typeable is concerned, Constraint and Type are synonymous.
4. On the Constraint v Type patch, restore the full power of KindCo. This
makes the type system broken, but I don't think the sky will come crashing
down.
5. Merge Constraint v Type after the branch is cut. This will make GHC
HEAD unsound in a new way, but no one will notice unless they try.
6. File a priority-highest bug to eliminate newtype-classes (which beget
heterogeneous axioms in the Constraint/=Type world).
7. Finish the first-class reification design and implement before 8.4.
8. Remove newtype-classes, thus eliminating heterogeneous axioms and the
unsoundness mentioned in (5).
This plan was met with general applause.
But a recent chat with Simon suggested a new direction, that would allow
us to separate Constraint from Type while keeping the efficiency of
newtype-classes. In brief:
* Allow representational casts in kinds, resurrecting sections 5 and 6
of an [http://cs.brynmawr.edu/~rae/papers/2015/equalities/equalities.pdf
unpublished paper of mine].
Currently, all kind-casts (that is, all uses of `CastTy` to change the
kind of a type) use nominal coercions. This means that if we separate
Constraint from Type, any equating of `C a` with `a` (in `class C a where
meth :: a`) will somehow lead to a nominal equality between Constraint and
Type, precisely the situation we wish to avoid. But if we allow
representational coercions in kinds, then we can arrange to have
`Constraint ~R Type` but not `Constraint ~N Type`. Indeed this makes more
intuitive sense, because `Constraint` and `Type` do have the same runtime
representation, but we wish to keep them separate regardless.
Sadly, representational coercions in kinds are troublesome, as described
[https://ghc.haskell.org/trac/ghc/wiki/DependentHaskell/Internal#RolesCoherenceandKinds
here] and in that unpublished paper. The paper details a kind system that
circumvents the problem, and thus presents a plausible way forward. But it
requires yet more wrinkles in GHC's coercion language. Is this worth it?
Perhaps. Previously, Simon vetoed that system as overly complicated. The
nub of his argument was that there was no point in having roles in kind-
coercions. But now, we have a reason to do this, so it might be well-
advised to revisit that decision. It's also possible that any wisdom I
have accumulated in the intervening years may come to bear and help us
out.
Another approach that we considered was to have three different, unrelated
arrow types: `(->) :: TYPE r1 -> TYPE r2 -> Type`, `(=>) :: Constraint ->
TYPE r -> Type`, `(=>) :: Constraint -> Constraint -> Type`, where the
last one is used to build dictionaries. Having these arrows like this
prevents the need for `KindCo` to work on representational coercions --
thus removing the incompatibility between the original solution proposed
in comment:47 and the work in Phab:D2038. This would work, and would allow
us to keep `C a ~R a`, but then we couldn't have `(C a => a) ~R (a -> a)`,
so the newtype-class efficiency would run out of gas fairly quickly.
I do think, in the long run, that having representational coercions in
kinds is the Right Answer, because it will be necessary to support
promoting newtypes to kinds, necessary for full
[http://cs.brynmawr.edu/~rae/papers/2016/thesis/eisenberg-thesis.pdf
dependent types].
I don't expect any action on this until the summer, at least, but I wanted
to jot it all down.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11715#comment:64>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list