[GHC] #11376: Inconsistent specified type variables among functions and datatypes/classes when using -XTypeApplications
GHC
ghc-devs at haskell.org
Tue Mar 29 17:45:53 UTC 2016
#11376: Inconsistent specified type variables among functions and datatypes/classes
when using -XTypeApplications
-------------------------------------+-------------------------------------
Reporter: RyanGlScott | Owner: goldfire
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler (Type | Version: 8.1
checker) | Keywords:
Resolution: | TypeApplications
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: Other | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by goldfire):
But this would lead to confusing behavior if there are any uninstantiated
specified variables. If we did instantiation, then `:t f` would answer
`Int -> Int -> Int`. That's reasonable enough, but then it's quite
surprising when `:t f @Int` is accepted! In a somewhat similar scenario,
say `bar :: forall a b. Show a => a -> b -> a`. What should `:t bar @Int`
say? I offer 4 choices:
1. `forall b. Show Int => Int -> b -> Int`
2. `forall b. Int -> b -> Int`
3. `forall {b}. Int -> b -> Int`
4. `Int -> b -> Int`
Here is how these could be produced:
1. This is what is currently done. No instantiation at `:type`.
2. This would require some new algorithm that instantiates a type and
regeneralizes, being very careful to somehow notice when the instantiated
variable arose from a specified variable and mark the re-generalized
variable as specified. This becomes quite hard (both to implement and to
specify) when equality constraints are in the mix and might combine a
specified variable with an invisible one.
3. Instantiate and regeneralize. But now it looks like `bar @Int @Bool`
should be rejected, even though it's actually OK.
4. Instantiate and do not regeneralize. Here, the user can't know that
`bar @Int @Bool` is OK, but at least we're not suggesting that it should
be rejected.
As you can see, I prefer (1). It's conceivable to make a different choice
when there are no top-level specified variables (so that a further type
parameter would be an error), but I don't think we should. (Before arguing
against me here, consider `quux :: forall a. Int -> forall b. Show a => b
-> a -> Bool`. What should `:type quux @Int` say?)
Another option I'd be happy with: Option (1) when `-fprint-explicit-
foralls` is on, and option (3) when it's not. This might be surprising to
users, but the benefits may outweigh the costs.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11376#comment:21>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list