
#11011: Type-indexed TypeReps, Static Pointers and Distributed Closures -------------------------------------+------------------------------------- Reporter: bjmprice | Owner: Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by goldfire): From the wiki:
To ease the transition we will provide both * The old API via a (deprecated) new module `Data.Typeable710`. * The old API via the exiting module `Data.Typeable` but with new names for (deprecated) old types and functions.
This doesn't appear to ease the transition to me. It means forcing users to make a choice: 1) be lazy and change your import, or 2) educate themselves about our new interface, which involves a non-trivial amount of whiz-bang new features. Many will choose (1), because many people are lazy, especially in the face of type theory. Then those people will have to change again. Furthermore, this violates the "3-year no-warning maintenance window" policy being formulated on the libraries@ list. And, with a little type-level hackery, I think we can have our cake and eat it to: use just 1 set of names for both APIs. To wit: {{{#!hs data TypeRep710 = forall a. TypeRep710 (TypeRep80 a) data TypeRep80 :: k -> * type family TypeRep :: k where TypeRep = TypeRep710 TypeRep = TypeRep80 class Typeable (a :: k) where typeRep# :: Proxy# a -> TypeRep80 a type family TypeRepKind res where TypeRepKind (proxy (a :: k) -> b) = k TypeRepKind (TypeRep80 (a :: k)) = k class TypeRepResult res where type TypeRepIndex res :: TypeRepKind res typeRep :: Typeable (TypeRepIndex res) => res instance (b ~ TypeRep710) => TypeRepResult (proxy a -> b) where type TypeRepIndex (proxy a -> b) = a typeRep (_ :: proxy a) = TypeRep710 (typeRep :: TypeRep80 a) instance TypeRepResult (TypeRep80 a) where type TypeRepIndex (TypeRep80 a) = a typeRep = undefined }}} This works on my branch. The following definitions also work: {{{#!hs foo :: TypeRep -> () foo = undefined bar :: TypeRep Int -> () bar = undefined }}} where the first gets `TypeRep710` and the second gets `TypeRep80`. We also conveniently have `typeRep :: Typeable a => proxy a -> TypeRep` (where that's the `TypeRep710`) and `typeRep :: Typeable a => TypeRep a` (where that's the `TypeRep80`). In a few years, we just remove the compatibility shim. :) Do I honestly think this is a good idea? I'm not sure. But I don't have a better one that will keep everyone happy. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11011#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler