Opened 4 years ago

Closed 2 years ago

#11400 closed bug (fixed)

* is not an indexed type family

Reported by: RyanGlScott Owned by:
Priority: normal Milestone: 8.2.2
Component: Compiler (Type checker) Version: 8.1
Keywords: TypeInType, TypeFamilies Cc: goldfire
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: GHC rejects valid program Test Case:
Blocked By: #11307 Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:


I can't seem to create an indexed data family using the kind * with -XTypeInType enabled. I have to work around it by using Type:

$ /opt/ghc/head/bin/ghci
GHCi, version 8.1.20160108:  :? for help
λ> :set -XTypeInType -XTypeFamilies 
λ> import Data.Kind
λ> data family IdxProxy k (a :: k)
λ> data instance IdxProxy * a

<interactive>:5:1: error:
    • Illegal family instance for ‘*’
        (* is not an indexed type family)
    • In the data instance declaration for ‘*’
λ> data instance IdxProxy Type a
λ> :kind! IdxProxy *
IdxProxy * :: * -> *
= IdxProxy *
λ> :kind! IdxProxy Type
IdxProxy Type :: Type -> *
= IdxProxy Type

Change History (12)

comment:1 Changed 4 years ago by RyanGlScott

Actually, this might just be a parser issue, not a data family issue. I can also get the above instance to work by typing it in as

data instance IdxProxy (*) a

Which leads me to believe that GHC is parsing data instance IdxProxy * a as data instance (*) IdProxy a—that is, it's interpreting * as an infix type operator (as evidence, typing in the latter declaration gets the same error message the former).

I'm not sure how tricky it would be to detangle the parser in this case, since I'm not sure how GHC knows to choose Data.Kind.* over an infix type operator that happens to be named *.

comment:2 Changed 4 years ago by jstolarek

I've run into the same problem. I think this is a wontfix. Richard promised to document the need for parens in the User's Guide, but I don't think he did that yet. Is this the relevant section:


comment:3 Changed 4 years ago by RyanGlScott

Indeed, having a complete rundown of where you need to parenthesize * would be extremely helpful. (I think you also need to parenthesize it when reexporting it, i.e., type (*), correct?)

comment:4 Changed 4 years ago by simonpj

Also doesn't TypeInType use "Type" in place of "*"? I'm a bit confused. Richard?

comment:5 Changed 4 years ago by jstolarek

I believe Type and * are synonyms. So theoretically they can be used interchangeably but practically there is this special case for parsing when * needs to be parenthesized.

comment:6 Changed 4 years ago by goldfire

This whole thing is very much a design compromise.

It would be fully backward compatible simply to disallow * in TypeInType code, in favor of Type. Of course it's backward compatible, as TypeInType is new. But it has a terrible migration story, because you can't use Type for * in GHC 7.x.

So I did a bit of parser hackery to get this to hold together. But it really only works when parsing a normal type. Other places where types appear in unusual situations don't work out so well. (For example, type instance heads and Haskell98 data constructors.) Could this be fixed? I'm sure it could, but it's quite painful each time.

I'm quite happy to change designs around this issue. Or for someone to do more parser hackery to get * to work in more contexts.

This ticket has the same fix as #11307, which is to have new abstract syntax for type instance heads.

comment:7 Changed 4 years ago by simonpj

Fair enough. But is the compromise documented in the user manual? Maybe so -- but if not, doing to would be very worth while.

comment:8 Changed 4 years ago by goldfire

Blocked By: 11307 added

Will clarify when I write the TypeInType documentation.

comment:9 Changed 4 years ago by thomie

Keywords: TypeFamilies added

comment:10 Changed 2 years ago by Richard Eisenberg <rae@…>

In c9667d3/ghc:

Fix #11400, #11560 by documenting an infelicity.

Really, the fix for both of these is #11307.

comment:11 Changed 2 years ago by goldfire

Status: newmerge

May as well merge the documentation update.

comment:12 Changed 2 years ago by bgamari

Milestone: 8.2.2
Resolution: fixed
Status: mergeclosed
Note: See TracTickets for help on using tickets.