rank 2-polymorphism and type checking
Ashley Yakeley
ashley@semantic.org
Sun, 28 Oct 2001 23:33:56 -0800
At 2001-10-24 01:08, Simon Peyton-Jones wrote:
>So I'm interested to know: if GHC allowed arbitrarily-ranked types, who
>would use them?
I would. Right now I have a class for 'IO lifted monads', that is, monads
from which one can call IO actions:
class (Monad m) => IOLiftedMonad m where
{
callIOWithMap :: ((m a -> IO a) -> IO b) -> m b;
callIO :: IO a -> m a;
callIO = callIOWithMap . const;
};
The 'callIOWithMap' function allows such things as 'catch' to be defined
over the monad:
class (IOLiftedMonad m) => IsJVMMonad m where
...
jvmCatch :: (IsJVMMonad m) => m a -> (JThrowable -> m a) -> m a;
jvmCatch foo catchClause = callIOWithMap (\map -> catch (map foo) (\x
-> map (do
{
exRef <- callIOWithEnv vmGetClearException;
noEx <- callIO (getIsNothing exRef);
if noEx
then (callIO (ioError x))
else catchClause (MkJVMRef exRef);
})));
Now this is fine, because both occurences of 'map' have the same type.
But I recently discovered this doesn't work if the map is used with
different types. For instance, GHC 5.02 won't compile this:
test :: (IOLiftedMonad m) => m a -> m b -> m (a,b);
test ma mb = callIOWithMap (\map -> do
{
a <- map ma;
b <- map mb;
return (a,b);
});
It looks like what I really need is this:
callIOWithMap :: ((forall a. (m a -> IO a)) -> IO b) -> m b;
Is that correct? But GHC doesn't allow it...
--
Ashley Yakeley, Seattle WA