foralls in class assertions

Ashley Yakeley ashley@semantic.org
Wed, 11 Sep 2002 00:32:56 -0700


At 2002-07-22 04:58, Simon Peyton-Jones wrote:

>This business of having 'foralls' in a context (whether for a class or
>a function) is not hard to implement in principle, but in practice it'd
>take few days of hacking I guess.  And, more to the point, thinking.
>What are the interactions with functional dependencies or implicit
>parameters?
>(Maybe none, but I've been caught before.)
>
>So it's really waiting for someone to say "having foralls in contexts
>would change my life and I would love you for ever", rather than "it'd
>be nice".
>
>Simon "lazy evaluation" PJ

OK, I can't say it would change my life but I did come up with a rather 
more motivating example. I guess the best I can offer is "I'll buy you a 
drink next time I'm back in Cambridge" (I have family there, so it does 
happen).

I want to implement typed exceptions somewhat similar to Java. Code would 
declare type using an "ExceptionMonad" of kind (* -> * -> *):

	  class (forall ex. Monad (mm ex)) =>
     ExceptionMonad mm where
     {
     throwX :: x -> mm x a
     catchX :: mm xa a -> (xa -> mm xb a) -> mm xb a;
     }

Notice how the types of throwX and catchX precisely mirror those of 
return and (>>=).

Now I could write code that throws different kinds of exceptions like 
this:

   data FooException = MkFooException String;

   foo :: (ExceptionMonad mm) => Char -> mm FooException Integer;
   foo c = ...

   data BarException = MkBarException | FooBarException FooException;

   bar :: (ExceptionMonad mm) => mm BarException Integer;
   bar = do
     {
     a <- catchX (foo 'q') (\fx -> throwX (FooBarException fx));
     return (a + 1);
     }

This allows you to have typed structured exceptions more easily, which I 
think is preferable in many cases to relying on "fail" with its String 
argument...


-- 
Ashley Yakeley, Seattle WA