Opened 19 months ago

Last modified 18 months ago

#11400 new bug

* is not an indexed type family

Reported by: RyanGlScott Owned by:
Priority: normal Milestone:
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 (9)

comment:1 Changed 19 months 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 19 months 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 19 months 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 19 months ago by simonpj

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

comment:5 Changed 19 months 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 19 months 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 19 months 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 19 months ago by goldfire

Blocked By: 11307 added

Will clarify when I write the TypeInType documentation.

comment:9 Changed 18 months ago by thomie

Keywords: TypeFamilies added
Note: See TracTickets for help on using tickets.