
#15561: TypeInType: Type error conditioned on ordering of GADT and type family definitions -------------------------------------+------------------------------------- Reporter: Bj0rn | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.6.1 Component: Compiler | Version: 8.4.3 Resolution: | Keywords: TypeInType, | TypeFamilies, GADTs 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: | -------------------------------------+------------------------------------- Comment (by simonpj): Yes, I think it's #12088 again. Here is what I think is going on. * The declaration {{{ type instance UnwrapAnyWrapperLikeThing ('Wrap a :: IndexWrapper [b]) = a }}} mentions `IndexWrapper`, so the latter must be typechecked first (and it is). * `IndexWrapper` is mutually recursive with `HasIndex` and `Index`, so they must be typechecked together (and they are). * Returning to {{{ type instance UnwrapAnyWrapperLikeThing ('Wrap a :: IndexWrapper [b]) = a }}} we can see that `a :: Index [b]`. Now, if we have already processed {{{ instance HasIndex [a] where type Index [a] = Int }}} then that mens `a :: Int`, and all is well. (This does involve some type family reduction in the patterns of a `type instance`. Where does that happen?) * But if we have not yet processed the instance for `HasIndex` then we complain that the LHS {{{ type instance UnwrapAnyWrapperLikeThing ('Wrap (a :: Index [b]) :: IndexWrapper [b]) = a }}} mentions `Index [b]` on the LHS. For now, a robust solution is to force GHC to deal with the instance of `HasIndex` first,(mis)-using a Template Haskell splice. For example, this compiles fine, but fails if you remove the splice {{{ type family UnwrapAnyWrapperLikeThing (a :: t) :: k class HasIndex a where type Index a emptyIndex :: IndexWrapper a data IndexWrapper a where Wrap :: Index a -> IndexWrapper a instance HasIndex [a] where type Index [a] = Int emptyIndex = Wrap 0 $([d| |]) -- Empty Template Haskell top level splice type instance UnwrapAnyWrapperLikeThing ('Wrap a :: IndexWrapper [b]) = a }}} More grist for the #12088 mill! -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15561#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler