[GHC] #11011: Type-indexed TypeReps, Static Pointers and Distributed Closures
GHC
ghc-devs at haskell.org
Mon Oct 26 13:24:28 UTC 2015
#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
More information about the ghc-tickets
mailing list