[GHC] #16320: Clean up printing of foralls
GHC
ghc-devs at haskell.org
Thu Feb 14 20:42:20 UTC 2019
#16320: Clean up printing of foralls
-------------------------------------+-------------------------------------
Reporter: goldfire | 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:
-------------------------------------+-------------------------------------
Simon and I agreed on several infelicities around the printing of types
with foralls. Before cleaning up the code, though, we wanted a
''specification'' of what we should do. Here is what we have.
When printing types for users (in GHCi and certain error messages), it is
convenient to sometimes suppress `forall`s. Given a type `ty` to print,
`forall`s will be suppressed when ''all'' of the following are true:
1. `-fprint-explicit-foralls` is not in effect.
2. The kinds of all bound type variables are Haskell98-style. That is, the
kinds consist only of `Type` and `->`.
3. No bound type variable is `Required`.
4. The `forall`s are all at the top. Exception: `forall`s are allowed to
be mixed with class constraints, but no `forall`s can appear under a
proper `->`.
5. No two quantified type variables are spelled the same.
This decision is made once, while looking at the overall type. Once made,
it is not challenged: either all `forall`s in a type are printed, or none
are.
Reasons behind the conditions:
1. No comment.
2. Currently, we print `forall k (a :: k). ...` when there is a bound type
variable with a variable kind. But, really, the fact that it's a variable
isn't the only way it could be interesting.
3. `Required` type variables must be supplied; omitting these would be
very confusing.
4. If a type has nested `forall`s, it's best to print. Reason for
exception: the type of `return` is properly `forall (m :: Type -> Type).
Monad m => forall (a :: Type). a -> m a`. Note that a `forall` is under a
class constraint. But we want to suppress the `forall`s there, too.
5. Imagine this abuse of our language:
{{{#!hs
class C a b where
meth :: forall a. a -> b
}}}
The type of `meth` is `forall a b. C a b => forall a. a -> b`. This is,
actually, a well-formed type, where one type variable shadows another. But
if we don't print the `forall`s, any reader will come to the wrong
conclusion about the meaning of the type.
This is a slight tweak to the current rules, meaning more `forall`s are
printed than previously. Pointedly, this will not happen in
Haskell98-style code, so they will not appear for beginners. The current
state of affairs is messy, on the other hand, where some `forall`s may be
suppressed in a type while others are printed, causing more trouble.
While in town, any fix should also address comment:17:ticket:11786, which
is about a seeming inefficiency of the implementation of
`eliminateRuntimeReps`.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/16320>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list