First-class types
Jan-Willem Maessen
jmaessen@MIT.EDU
Tue, 04 Mar 2003 10:07:40 -0500
Simon PJ replies:
> Ingenious, but unnecessarily complicated. You don't need existential
> types at all.
> (See the code below, which is considerably simpler and, I fancy, a bit
> more efficient.) Also, I'm not sure why you make 'Type' (which is
> pretty much the Typable class in the Dynamic library) into a superclass
> of D; it's not used. The idea of using a value (which is never
> evaluated) as a proxy for a type is exactly what the Typable class does.
> Indeed, it is a really useful technique.
I agree. I like it when this sort of thing can be reduced to just a
few lines of code.
I suspect it is possible to turn "coerce" and/or "typeof" into some
sort of "asTypeOf"-like operator and avoid the creation of undefined
proxies for the result type. Indeed, perhaps we want a definition
such as this (untested, but probably subtly wrong):
> class (Coerce a1 b, Coerce a2 b) => D a1 a2 b | a1 a2 -> b where
> lift2 :: (b -> b -> b) -> a1 -> a2 -> b
> lift2 op = op'
> where op' a b = op (coerce a) (coerce b)
>
> class Coerce a b where
> coerce :: a -> b
>
> -- lots of instances here.
>
> add = lift2 (+)
> sub = lift2 (-)
In general, if D is being used only to define coercions on a binary
operation, thenin my opinion the class method ought to be a coercion
on a binary operation.
But I had a couple of questions for the avid type-hackers out there,
motivated by this example and by similar examples from my own
tinkerings:
1) Coerce a a can be defined as coerce=id for all a. However, this
may of course lead to overlap in the type structure, so we must
write a separate instance definition for Coerce Int Int, Coerce
Double Double, etc. if we want types to be decidable. I'd love for
some clever person to solve this little difficulty.
2) When we define D a b c, we know that D b a c is also allowed.
Again, decidability prevents us from asserting this directly.
Again, a clever solution could save us a lot of code and even more
debugging. I suspect this may be a marginally easier nut to crack
than the previous one.
So, type hackers, can you come up with a Byzantine set of classes
which encode these restrictions nicely and decidably?
-Jan-Willem Maessen
[Note that I suspect that it maybe possible to *prove* that you can't,
at least for case 1. If you're really ambitious, you might want to
attack transitivity of coercion, too.]