[GHC] #13401: GHCi gives conflicting information about visible type application
GHC
ghc-devs at haskell.org
Thu Mar 9 17:01:31 UTC 2017
#13401: GHCi gives conflicting information about visible type application
-------------------------------------+-------------------------------------
Reporter: crockeea | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone:
Component: GHCi | Version: 8.0.1
Resolution: | Keywords:
| TypeApplications
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: #11376, #11975 | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Changes (by RyanGlScott):
* related: => #11376, #11975
Comment:
What prompted this is chronicled in #11376 (particularly from
[https://ghc.haskell.org/trac/ghc/ticket/11376#comment:15 comment:15]
onward). It was discovered that when `:type` was used with a visibly
applied type, you could get some weird results, like this one:
{{{
λ> import GHC.Generics
λ> :type datatypeName @('MetaData "Void" "Data.Void" "base" 'False)
datatypeName @('MetaData "Void" "Data.Void" "base" 'False)
:: Datatype ('MetaData "Void" "Data.Void" "base" 'False) =>
forall k1 (t :: Meta -> (k1 -> *) -> k1 -> *) (f :: k1
-> *) (a :: k1).
t ('MetaData "Void" "Data.Void" "base" 'False) f a -> [Char]
}}}
Before, `:type` was instantiating constraints lazily, which is why that
`Datatype` constraint is still lingering around in the type that `:type`
infers above, even though `'MetaData "Void" "Data.Void" "base" 'False`
should discharge that constraint. simonpj thought this was ghastly and
changed the behavior of `:type` to //deeply// instantiate the inferred
type (i.e., solve constraints as much as possible) and re-generalize
afterwards.
(Note: "generalize" comes from a rule in Hindley–Milner type inference, I
believe, where you infer a type of the form `forall a. ...`).
After this change, you get this instead:
{{{
λ> :type datatypeName @('MetaData "Void" "Data.Void" "base" 'False)
datatypeName @('MetaData "Void" "Data.Void" "base" 'False)
:: t ('MetaData "Void" "Data.Void" "base" 'False) f a -> [Char]
}}}
which is certainly nicer to look at. But it comes at a downside: deep
instantiation followed by re-generalization can change the visibilities of
type parameters, which explains the behavior you reported originally in
this ticket. To work around this, goldfire introduced `:type +v` in
#11975, which gives you the original lazy instantiation behavior that
`:type` used to have.
OK, that ended being a much lengthier explanation that I'd hoped for.
Hopefully, you understand the context of this a little better. My question
to you is now: how should we update the users' guide to explain this
wrinkle? I'm a bit reluctant to include a crash-course on HM type
inference, but maybe there's an instructive way to give the highlights of
this discussion to readers.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13401#comment:4>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list