[GHC] #11620: RFC: Type-class type signatures (:: Constraint)

GHC ghc-devs at haskell.org
Mon Feb 22 02:30:13 UTC 2016


#11620: RFC: Type-class type signatures (:: Constraint)
-------------------------------------+-------------------------------------
        Reporter:  Iceland_jack      |                Owner:
            Type:  feature request   |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.1
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by goldfire):

 I actually ran into this problem in a different context, where the problem
 was not just cosmetic.

 Short version: we should devise a syntax where a user can give a full kind
 signature for a class while binding type variables appropriately. I'm not
 sure what this syntax would be.

 Long version: I had this type:

 {{{#!hs
 data TypeRep (a :: k) where ...
 }}}

 I needed an existential wrapper around this type, something like

 {{{#!hs
 data TypeRepX1 where
   TypeRepX1 :: forall k (a :: k). TypeRep a -> TypeRepX1
 }}}

 But that turned out not to work for me, because it imposes no constraint
 at all on `k` or `a`. So I wanted a version of `TypeRepX` that is
 parameterized by a constraint that will be applied to `a`. If the
 existential `a` is still to be kind-polymorphic, then we have to make the
 constraint kind-polymorphic, too:

 {{{#!hs
 data TypeRepX :: (forall k. k -> Constraint) -> Type where
   TypeRepX :: forall (c :: forall k1. k1 -> Constraint) k (a :: k).
               c a => TypeRep a -> TypeRepX c
 }}}

 (Sadly, I need to put the kind on `c` explicitly, because GHC won't infer
 kinds with `forall`s, lest things become impredicative. But it's not so
 bad, really, to put the signature on.)

 This actually all works quite well, to my great delight when I first tried
 it.

 Then, I wanted to use the constraint `((~~) Bool)`. That is, I wanted to
 insist that the type `a` is in fact `Bool`. I used heterogeneous equality
 so that it would all be kind-polymorphic. However, note that

 {{{#!hs
 (~~) :: forall k1 k2. k1 -> k2 -> Constraint`
 }}}

 and thus that

 {{{#!hs
 (~~) Bool :: k2 -> Constraint
 }}}

 for some `k2`. That is, the original `forall` is too far to the left. As
 you will see in the "Practical type inference" paper, the kind of `(~~)`
 is too specific; it should really be `forall k1. k1 -> forall k2. k2 ->
 Constraint`. But we have no way of requesting such a kind without being
 able to specify the full kind signature of a class. (In the case of
 `(~~)`, GHC could just do this by fiat. But it would be unsporting for me
 to do this for `(~~)` without letting you do it for your constraints.)

 Bottom line: it would increase the expressiveness of Haskell to be able to
 specify a full kind.

 But what about syntax?? I'm a bit stuck there.

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


More information about the ghc-tickets mailing list