Casting dynamic values

Alastair David Reid reid@cs.utah.edu
27 Nov 2001 17:31:10 -0700


George Russell <ger@tzi.de> writes:

> cast :: (Typeable a,Typeable b) => a -> Maybe b
> cast = fromDynamic . toDyn
>
> My question is: is this the most efficient way of doing it, or is
> there a better way?

I think I'd do it that way.  toDyn and fromDynamic are both pretty
simple functions.

  toDyn x pairs x with a representation of its type.
  fromDynamic checks the type is correct and returns x.

That is, the cost is:

1. construct the representation of type a
2. construct the pair
3. deconstruct the pair
4. construct the representation of type b
5. compare the representations of types a and b

If GHC is able to inline these functions, construction and
deconstruction of the pair can probably be eliminated.  

That leaves just building the representations and comparing them.  I
believe GHC could construct the representations at compile time - all
it has to do is inline some pretty-trivial method bodies.

It'd be nice if GHC could perform some parts of the comparision at
compile time.  For example:

   Int =?= Int    ->  True
   Int =?= Float  ->  False
   [a] =?= [b]    ->  [a] =?= [b]

But I don't think GHC can do this because AFAIK, GHC will not reduce
literal string comparisions at compile time.

   "Int" == "Int"               ->  True
   "Int" == "Float"             ->  False
   App "List" a == App "List" b ->  "List" == "List" && a == b
                                ->  True && a == b
                                ->  a == b

[This is assuming that GHC's implementation of Typeof still uses
strings.  This may not be true though since there was talk of adding
direct compiler support to make the implementation of typeof more
efficient and, more importantly, less prone to programmer error.  The
motivation to do this was the realization that one could break type
safety by writing a bad instance of typeof.]

-- 
Alastair Reid        reid@cs.utah.edu        http://www.cs.utah.edu/~reid/