[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