simulating dynamic dispatch

Simon Peyton-Jones simonpj@microsoft.com
Fri, 4 Apr 2003 16:11:45 +0100


(Taking this off to haskell-cafe)

It's not unreasonable for it to be ambiguous.  The argument 'f' says
*forall b*.  The cast will cast to a *specified* type.  But you aren't
specifying the type.

If you passed a less polymorphic 'f' it might be ok.

Simon

| -----Original Message-----
| From: Hal Daume III [mailto:hdaume@ISI.EDU]
| Sent: 21 March 2003 22:29
| To: Simon Peyton-Jones
| Cc: oleg@pobox.com; haskell@haskell.org
|=20
| Excellent paper!  I have started using some of the techniques already!
|=20
| But, back to the real question :).  I now no longer think such a thing
is
| possible.  Essentially what I want (given 'cast :: Typeable a,
Typeable b
| =3D> a -> Maybe b' [1]), is to write something like:
|=20
| test :: forall a r . Typeable a =3D>
|         (forall b . (Typeable b, Foo b) =3D> b -> r) ->
|         a -> Maybe r
| test f a =3D liftM f (cast a)
|=20
| but then 'b' is ambiguous.  I'm not sure there is any way around
| this.  Can someone help?
|=20
|  - Hal
|=20
| [1] is there any reason why parens are requires around class
| contexts?  i've always found this odd...
|=20
| --
|  Hal Daume III                                   | hdaume@isi.edu
|  "Arrest this man, he talks in maths."           | www.isi.edu/~hdaume
|=20
| On Fri, 21 Mar 2003, Simon Peyton-Jones wrote:
|=20
| > You might also find the 'cast' function in Section 3 of "Scrap your
| > boilerplate" useful.
| > http://research.microsoft.com/~simonpj/papers/hmap/
| > I'm not certain, but it has the right smell.
| > Simon
| >
| > | -----Original Message-----
| > | From: oleg@pobox.com [mailto:oleg@pobox.com]
| > | Sent: 21 March 2003 04:19
| > | To: hdaume@ISI.EDU; haskell@haskell.org
| > | Subject: Re: simulating dynamic dispatch
| > |
| > |
| > | > i'm hoping to be able to simulate a sort of dynamic dispatch
based
| > on
| > | > class instances.
| > |
| > | It seems you want to dispatch based not on a type but on the
| > | constraint of a type.
| > |
| > | You code almost worked. Here's the a bit updated and working
version.
| > |
| > | class Foo a where { foo :: a -> Bool }
| > | class Bar a where { bar :: a -> Bool }
| > |
| > | data FB =3D forall a . Foo a =3D> MkFoo a | forall a . Bar a =3D> =
MkBar
a
| > |
| > | instance Foo FB where
| > |     foo (MkFoo x) =3D foo x
| > |
| > | instance Bar FB where
| > |     bar (MkBar x) =3D bar x
| > |
| > | -- some instances for the test
| > | instance Foo Int where
| > |     foo x =3D x =3D=3D 0
| > |
| > | instance Bar Char where
| > |     bar x =3D x =3D=3D 'a'
| > |
| > |
| > | test x =3D case x of
| > |           (MkFoo a) -> Just $ foo a
| > |           (MkBar a) -> Just $ bar a
| > | --	  _         -> Nothing
| > |
| > |
| > | -- *Main> test $ MkFoo (0::Int)
| > | -- Just True
| > | -- *Main> test $ MkFoo (10::Int)
| > | -- Just False
| > | -- *Main> test $ MkBar 'a'
| > | -- Just True
| > | -- *Main> test $ MkBar 'b'
| > | -- Just False
| > |
| > | _______________________________________________
| > | Haskell mailing list
| > | Haskell@haskell.org
| > | http://www.haskell.org/mailman/listinfo/haskell
| >