[GHC] #9858: Typeable instances should be kind-aware (was: Typeable instance for datatype and its promoted constructor is the same)

GHC ghc-devs at haskell.org
Thu Jan 22 13:04:19 UTC 2015


#9858: Typeable instances should be kind-aware
-------------------------------------+-------------------------------------
        Reporter:  dreixel           |                   Owner:  dreixel
            Type:  bug               |                  Status:  new
        Priority:  highest           |               Milestone:  7.10.1
       Component:  Compiler          |                 Version:  7.9
      Resolution:                    |                Keywords:
Operating System:  Unknown/Multiple  |            Architecture:
 Type of failure:  None/Unknown      |  Unknown/Multiple
      Blocked By:                    |               Test Case:
 Related Tickets:                    |                Blocking:
                                     |  Differential Revisions:
-------------------------------------+-------------------------------------

Comment (by simonpj):

 Richard is spot on.

 For (1), really `A` and `'A` are entirely different, and should not
 compare as equal.  That is probably easy to fix, by changing the
 fingerprint we generate for `'A`.

 For (2), yes absolultely, just as `Maybe Int` and `Maybe Bool` should have
 non-equal `TypeRep`s, so should `B 'Ordering` and `B 'Bool`. The fact that
 is's a kind application isn't important.  The ''reason'' that bug (2)
 happens is, I think, that the `Typeable` instance of `B` is generated by
 an instance declaration:
 {{{
 instance Typeable B where
   typeRep# _ = ...the TyCon for B....
 }}}
 This instance declaration is treated as ''source code'', and source code
 does implicit kind instantiation.  So we actually get
 {{{
 dfun :: forall k. Typeable (B k)
 dfun = /\k. MkTypeableDict (...TyCon for B....)
 }}}
 We don't want this!  Instead we want to treat `(B 'Bool)` just like `Maybe
 Bool`, using the application instance (in `Data.Typeable.Internals`),
 which looks roughly like this:
 {{{
 instance (Typeable s, Typeable a) => Typeable (s a) where
          -- See Note [The apparent incoherence of Typable]
   typeRep# _ = typeRep a `mkAppTy` typeRep b
 }}}
 We would like this to be done for ''kind'' applications as well as
 ''type'' applications.

 So we need two changes
  * For type constructors, we need an instance that truly matches on `B`
 not on `B k`
  * We need to decompose kind applications as we do type applications.

 To me it seems clear that we should move to treating `Typeable` more like
 we treat `Coercible`, i.e. as a built-in type class that the constraint
 solver knows how to solve, rather than as something handed with source-
 level instance declarations.

 That would imply:

  * There would be no `Typeable` instances in the instance environment
 (which itself would be a modest saving).

  * Either
    1. every data type constructor automatically has a `Typeable` instance
 (which I favour), or
    1. we'd need a tiresome separate mechanism (a flag in the `TyCon`) to
 say whether it does or does not have a `Typeable` instance.

 Note that this path might ultimately allow us to have a `TypeRep` for a
 polymorphic type, which we can't do right now.

 What do people feel about (1) vs (2)?  Why would we ever want a type
 ''not'' to be `Typeable`?  Note that the code-size overhead is modest: a
 single top-level definition of a record defining the `TyCon`.

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


More information about the ghc-tickets mailing list