Type families in kind signatures with TypeInType
Should the code below work in GHC 8.0.1? {-# LANGUAGE TypeInType, TypeFamilies #-} import Data.Kind (Type) type family K t :: Type type family T t :: K t -> Type data List type instance K List = Type type instance T List = [] Right now, I get an error like this one: min.hs:12:24: error: • Expected kind ‘K List -> Type’, but ‘[]’ has kind ‘* -> *’ • In the type ‘[]’ In the type instance declaration for ‘T’ which is puzzling, since K List -> Type and * -> * should be the same. Obviously, TypeInType is experimental and incomplete. I’m just wondering if this sort of thing is expected to work, or if I’m doing something not yet supported or never to be supported In particular, the kind signature for T is forall t -> K t -> Type, which looks like DependentHaskell. -- Dave Menendez <dave@zednenem.com> <http://www.eyrie.org/~zednenem/>
This is an example of https://ghc.haskell.org/trac/ghc/ticket/12088. The “type instance T List” declaration actually depends on the “type instance K List” declaration; the latter must be typechecked before the former. But this dependency is absolutely unclear. There’s a long discussion on the thread. Bottom line: we don’t know a solid automated way to spot this kind of problem, so I think we are going to ask for programmer assistance. In this case, we’d put a “separator” after the “type instance K List” decl, to explain that it must be done first: type instance K List = Type =========== type instance T List = [] Currently you have to write $(return []) to get the separator, but I think we’ll add a special separator. Simon From: Glasgow-haskell-users [mailto:glasgow-haskell-users-bounces@haskell.org] On Behalf Of David Menendez Sent: 23 September 2016 05:48 To: glasgow-haskell-users@haskell.org Mailing List <Glasgow-haskell-users@haskell.org> Subject: Type families in kind signatures with TypeInType Should the code below work in GHC 8.0.1? {-# LANGUAGE TypeInType, TypeFamilies #-} import Data.Kind (Type) type family K t :: Type type family T t :: K t -> Type data List type instance K List = Type type instance T List = [] Right now, I get an error like this one: min.hs:12:24: error: • Expected kind ‘K List -> Type’, but ‘[]’ has kind ‘* -> *’ • In the type ‘[]’ In the type instance declaration for ‘T’ which is puzzling, since K List -> Type and * -> * should be the same. Obviously, TypeInType is experimental and incomplete. I’m just wondering if this sort of thing is expected to work, or if I’m doing something not yet supported or never to be supported In particular, the kind signature for T is forall t -> K t -> Type, which looks like DependentHaskell. -- Dave Menendez <dave@zednenem.com<mailto:dave@zednenem.com>> <http://www.eyrie.org/~zednenem/<https://na01.safelinks.protection.outlook.com/?url=http:%2f%2fwww.eyrie.org%2f~zednenem%2f&data=01%7C01%7Csimonpj%40microsoft.com%7C740be9e2f66146e93b1308d3e36cdcda%7C72f988bf86f141af91ab2d7cd011db47%7C1&sdata=r83909O38f2c%2feaujupnsW%2fSy23XLouk2unQBGTCB8w%3d>>
On Fri, Sep 23, 2016 at 3:19 AM, Simon Peyton Jones <simonpj@microsoft.com> wrote:
This is an example of https://ghc.haskell.org/trac/ghc/ticket/12088.
Interesting. Is this case also an example, or is it a non-feature? class C t where type K t :: Type type T t :: K t -> Type m :: t -> T t a min.hs:21:17: error: • Type constructor ‘K’ cannot be used here (it is defined and used in the same recursive group) • In the kind ‘K t -> Type’ Failed, modules loaded: none. GHC accepts this if K t is moved outside of C.
The “type instance T List” declaration actually depends on the “type instance K List” declaration; the latter must be typechecked before the former. But this dependency is absolutely unclear. There’s a long discussion on the thread. Bottom line: we don’t know a solid automated way to spot this kind of problem, so I think we are going to ask for programmer assistance. In this case, we’d put a “separator” after the “type instance K List” decl, to explain that it must be done first:
type instance K List = Type
===========
type instance T List = []
Currently you have to write $(return []) to get the separator, but I think we’ll add a special separator.
Yes, this works. Thanks. It would be disappointing if this is the best we can do, but I guess other dependent languages don’t need to deal with open type families and everything being potentially mutually recursive. -- Dave Menendez <dave@zednenem.com> <http://www.eyrie.org/~zednenem/>
Interesting. Is this case also an example, or is it a non-feature? class C t where type K t :: Type type T t :: K t -> Type m :: t -> T t a Ah, that’s quite different! We should do strongly-connected-component analysis of the associated-type declarations within a single class declaration…. but we don’t currently do that. No difficulty in principle, I think. You could open a ticket. (Do include a link to this email thread and to #12088) Simon From: d4ve.menendez@gmail.com [mailto:d4ve.menendez@gmail.com] On Behalf Of David Menendez Sent: 23 September 2016 19:51 To: Simon Peyton Jones <simonpj@microsoft.com> Cc: glasgow-haskell-users@haskell.org Mailing List <Glasgow-haskell-users@haskell.org> Subject: Re: Type families in kind signatures with TypeInType On Fri, Sep 23, 2016 at 3:19 AM, Simon Peyton Jones <simonpj@microsoft.com<mailto:simonpj@microsoft.com>> wrote: This is an example of https://ghc.haskell.org/trac/ghc/ticket/12088. Interesting. Is this case also an example, or is it a non-feature? class C t where type K t :: Type type T t :: K t -> Type m :: t -> T t a min.hs:21:17: error: • Type constructor ‘K’ cannot be used here (it is defined and used in the same recursive group) • In the kind ‘K t -> Type’ Failed, modules loaded: none. GHC accepts this if K t is moved outside of C. The “type instance T List” declaration actually depends on the “type instance K List” declaration; the latter must be typechecked before the former. But this dependency is absolutely unclear. There’s a long discussion on the thread. Bottom line: we don’t know a solid automated way to spot this kind of problem, so I think we are going to ask for programmer assistance. In this case, we’d put a “separator” after the “type instance K List” decl, to explain that it must be done first: type instance K List = Type =========== type instance T List = [] Currently you have to write $(return []) to get the separator, but I think we’ll add a special separator. Yes, this works. Thanks. It would be disappointing if this is the best we can do, but I guess other dependent languages don’t need to deal with open type families and everything being potentially mutually recursive. -- Dave Menendez <dave@zednenem.com<mailto:dave@zednenem.com>> <http://www.eyrie.org/~zednenem/<https://na01.safelinks.protection.outlook.com/?url=http:%2F%2Fwww.eyrie.org%2F~zednenem%2F&data=01%7C01%7Csimonpj%40microsoft.com%7C89f26f5e599e49b96e0c08d3e3e29e26%7C72f988bf86f141af91ab2d7cd011db47%7C1&sdata=c8g6ahf%2F8lun%2BPBof97s03XbePVwT4Buh6ef2bDSjLg%3D&reserved=0>>
On Fri, Sep 23, 2016 at 3:00 PM, Simon Peyton Jones <simonpj@microsoft.com> wrote:
Interesting. Is this case also an example, or is it a non-feature?
class C t where
type K t :: Type
type T t :: K t -> Type
m :: t -> T t a
Ah, that’s quite different! We should do strongly-connected-component analysis of the associated-type declarations within a single class declaration…. but we don’t currently do that. No difficulty in principle, I think.
You could open a ticket. (Do include a link to this email thread and to #12088)
I’ve opened ticket #12612 <https://ghc.haskell.org/trac/ghc/ticket/12612>. Assuming GHC accepted this definition, would the Template Haskell trick (or whatever replaces it) allow defining instances of C? -- Dave Menendez <dave@zednenem.com> <http://www.eyrie.org/~zednenem/>
participants (2)
-
David Menendez -
Simon Peyton Jones