[GHC] #13399: Location of `forall` matters with higher-rank kind polymorphism

GHC ghc-devs at haskell.org
Thu Mar 9 14:44:29 UTC 2017


#13399: Location of `forall` matters with higher-rank kind polymorphism
-------------------------------------+-------------------------------------
        Reporter:  crockeea          |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.0.2
      Resolution:                    |             Keywords:  TypeInType
Operating System:  Unknown/Multiple  |         Architecture:
 Type of failure:  GHC rejects       |  Unknown/Multiple
  valid program                      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------
Changes (by RyanGlScott):

 * cc: goldfire (added)


Comment:

 This does indeed seem strange. Simon is right that there aren't many
 examples of higher-rank kinds in the wild from which to draw inspiration
 (OtToMH, I can only think of
 [https://github.com/goldfirere/triptych/blob/2e21a6be4419873c77a02c9a198379c76947b94c/extensibility/Extensible6.hs
 this example] from A Dependent Haskell Triptych). But I agree that there
 appears to be some inconsistencies between the ways that higher-rank types
 and higher-rank kinds are handled.

 Some other oddities: if you define this:

 {{{#!hs
 data Foo :: (* -> *) -> (forall k. k -> *)
 }}}

 and type `:i Foo` into GHCi, you get this back:

 {{{
 type role Foo phantom nominal phantom
 data Foo (a :: * -> *) k (c :: k)
 }}}

 This seems to imply that `Foo` has three visible type parameters, which
 isn't true at all!

 Moreover, this works:

 {{{#!hs
 data Foo :: (* -> *) -> (k -> *)
 type Goo = Foo
 }}}

 But this does not:

 {{{#!hs
 data Foo :: (* -> *) -> (forall k. k -> *)
 type Goo = Foo
 }}}

 {{{
     • Expecting two more arguments to ‘Foo’
       Expected kind ‘k0’,
         but ‘Foo’ has kind ‘(* -> *) -> forall k. k -> *’
     • In the type ‘Foo’
       In the type declaration for ‘Goo’
 }}}

 This seems to be exclusive to higher-rank kinds, as the type-level
 equivalents work just fine:

 {{{
 λ> let foo1 :: (* -> *) -> (k -> *); foo1 = undefined
 λ> let goo1 = foo1
 λ> let foo2 :: (* -> *) -> (forall k. k -> *); foo2 = undefined
 λ> let goo2 = foo2
 }}}

 goldfire, is this expected behavior? And are these idiosyncrasies
 documented somewhere? I find the current behavior extremely confusing.

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13399#comment:5>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list