pattern-matching extension?

Fergus Henderson fjh at cs.mu.OZ.AU
Mon Dec 8 15:37:46 EST 2003


On 05-Dec-2003, Derek Elkins <ddarius at hotpop.com> wrote:
> "Abraham Egnor" <aegnor at antioch-college.edu> wrote:
> > I've occasionally wanted some sort of equivalent of an instanceOf
> > function in haskell, i.e. one that would let me define a function that
> > could dispatch on the type of its argument as well as the value.  One
> > option I've seen for this is
> > "http://okmij.org/ftp/Haskell/class-based-dispatch.lhs", but that
> > unfortunately has the downside of requiring you to write both a
> > constructor for PACK and an instance of Packable for each type you'd
> > like to dispatch on.
> > 
> > The thought occurred to me that it is (intuitively) natural to do this
> > via extending the pattern-matching facility to include types as well
> > as literal values, i.e. something like:
> > 
> > f :: a -> String
> > f (a :: Int) = "got an int, incremented: "++(show (a+1))
> > f (a :: Show q => q) = "got a showable: "++(show a)
> > f _ = "got something else"
> > 
> > This has a couple of nice features - it's a simple extension of the
> > syntax, and acts as a sort of type-safe typecast.  However, I have
> > zero knowledge of how hard it would be to implement this, and there
> > may be theoretical difficulties I haven't seen.  Thoughts?
...
> data Showable = forall a. Show a => Showable a
> 
> instance Show Showable where
>     show (Showable showable) = show showable
> 
> -- extension: pattern guards (I think Hugs has them but I don't think
> -- NHC does. They are only used for prettiness here.)
> f :: Dynamic -> String
> f val | Just (a :: Int) <- fromDynamic val
>             = "got an int, incremented: "++show (a+1)
>       | Just (a :: Showable) <- fromDynamic val
>             = "got a showable: "++show a

Casting to a "Showable" is not the same as a dynamic class cast.  For the
approach that you have suggested to work, the user of this function f
would need to explicitly wrap up any showable values in a "Showable"
before calling f.  This is a leaky abstraction: in general the caller
may need to know a lot about the implementation of f in order to call
it properly.  So it would be nice to have a way of doing dynamic class
cast, rather than just dynamic type cast.

However, there are some theoretical difficulties with dynamic type
class cast.  In particular, it has some nasty interactions with dynamic
loading.  If you dynamically load a new module which has some new instance
declarations, then it may affect the results of dynamic type class casts.

-- 
Fergus Henderson <fjh at 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.


More information about the Haskell mailing list