hi all, i'm hoping to be able to simulate a sort of dynamic dispatch based on class instances. basically a function which takes a value and depending on what classes it is an instance of, does something. a simple example might be a 'maybeShow' function which sematically looks like:
maybeShow x | typeOf x `instanceOf` Show = show x | otherwise = "?"
I've been trying for a while to simulate something along the lines of:
class Foo a where { foo :: a -> Bool } class Bar a where { bar :: a -> Bool } foo x | typeOf x `instanceOf` Foo = Just (foo x) | typeOf x `instanceOf` Bar = Just (bar x) | otherwise = Nothing
and I tried using dynamics but those require instances of typeable on universally quantified types, which doesn't work out too well in practice. also, we can do class sums using existential types:
data FB = forall a . Foo a => MkFoo a | forall a . Bar a => MkBar a
and i tried something like: class FooBar a where wasFoo :: a -> Maybe FB -- will be MkFoo wasBar :: a -> Maybe FB -- will be MkBar wasFoo _ = Nothing wasBar _ = Nothing instance Foo a => FooBar a where wasFoo a = Just (MkFoo a) instance Bar a => FooBar a where wasBar a = Just (MkBar a) but this complains about duplicate instance declarations (for obvious reasons). i'm hoping one of the type class gurus out there can help me. Thanks in advance! -- Hal Daume III | hdaume@isi.edu "Arrest this man, he talks in maths." | www.isi.edu/~hdaume
On 20-Mar-2003, Hal Daume III <hdaume@ISI.EDU> wrote:
i'm hoping to be able to simulate a sort of dynamic dispatch based on class instances. basically a function which takes a value and depending on what classes it is an instance of, does something.
I call this feature "dynamic type class casts". But there are some difficulties in defining the semantics of this. What should it mean in the presence of dynamic loading? If you're allowed to dynamically load new modules that might contain new instance declarations, and you're allowed to check (in a non-IO-monad context) whether a type is an instance of a type class, and you want things to remain referentially transparent, then you've got a problem.
i tried something like:
class FooBar a where wasFoo :: a -> Maybe FB -- will be MkFoo wasBar :: a -> Maybe FB -- will be MkBar wasFoo _ = Nothing wasBar _ = Nothing
instance Foo a => FooBar a where wasFoo a = Just (MkFoo a)
instance Bar a => FooBar a where wasBar a = Just (MkBar a)
but this complains about duplicate instance declarations (for obvious reasons).
You can use instance declarations for whichever ground types you need, e.g. instance FooBar Int where ... instance FooBar String where ... -- Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit The University of Melbourne | of excellence is a lethal habit" WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
participants (2)
-
Fergus Henderson -
Hal Daume III