简体   繁体   中英

Typeable Instances for Temporary Types

I am trying to make a reified (using Data.Reflection ) type an instance of Typeable.

newtype Zq q = Zq Int

I can derive a Typeable1 instance for Zq , but this comes with the implicit constraint (Typeable q) . I want to use a value of type Zq q in a function which requires the argument to be Typeable . So there are a few questions:

  1. Is there any way to make a reified type Typeable ?
  2. If not, is there any way to modify the existing library to allow for this?
  3. In general, which types can be made Typeable ? It seems that by using DeriveDataTypeable and StandaloneDeriving , any concrete type I can think of (aside from a temporary type like the reified type) can be an instance.

EDIT Code snippet of what I'm talking about:

f = reify (42::Int) (\ (_::Proxy q) ->
  let x = Zq 15 :: Zq q -- x = 15 mod 42
  in ... 

I would like Zq q , where q is the reified type, to be an instance of Typeable . The only way I know to do this is to make q Typeable as well. Of course, if I reify 42 to q1 and then reify 43 to q2 , these should not be equal types. On the other hand, I realize I cannot expect two different type variables which reify the same value to have equal TypeReps (even though in practice they are identical).

It depends.

*Main> :t (Zq 42, Zq 42)
(Zq 42, Zq 42) :: (Zq q, Zq q1)
*Main> :t [Zq 42, Zq 42]
[Zq 42, Zq 42] :: [Zq q]
*Main>

The elements of the pair have different types, while the elements of the list are natutally of the same type. No surprise here.

If you want to keep it this way, it appears impossible to make Zq q typeable. The whole point of Typeable is that identical types get identical representations, while distinct types get distinct representations. The whole point of phantom types is just the opposite, to generate a new unique type at every opportunity. The type class mechanism does not support this kind of abuse. We would need a new unique TypeRep whenever our value is bound to something with a new type variable, or something like that.

OTOH if you want Zq q and Zq q1 to be convertible to each other even if q and q1 are distinct, you just write an instance of Typeable (Zq a) by hand. Make typeOf return a TypeRep that an automatically generated instance for

newtype Zq = Zq Int

would return.

Disclaimer: I have no idea what I'm talking about, honest!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM