[Haskell-cafe] Rank-2 types in classes

oleg at okmij.org oleg at okmij.org
Thu Mar 3 09:06:43 CET 2011


Yves Pare`s  wrote:
> I'm working on a library which aims to be a generic interface for 2D
> rendering. To do that, one of my goals is to enable each implementation of
> this interface to run in its own monad (most of the time an overlay to IO),
> thus giving me the following class
>
> class (Monad (IM i x)) => Impl i x where
>     data IM i x :: * -> *
>
> (where IM means Implementation Monad)
>
> I would like to write something like :
>
> class (forall x. Monad (IM i x)) => Impl i where
>     data IM i :: * -> * -> *

It is not clear if the class constraint is really needed. As an aside,
a class constraint is perhaps a bit of mis-feature of type classes: it sure
improves convenience by making signatures shorter. But it isn't really
necessary. Perhaps there are other, better ways of achieving the
convenience (the constraint alias proposal comes to mind).

If we drop the class constraint, we can move Monad (IM i x) as the
constraint on specific methods of the Impl class. The implicit uiniversal
quantification on x is well allowed then. For example:

> class Impl (i :: * -> *) where
>     data IM i :: * -> * -> *
>     foo :: Monad (IM i x) => Int -> IM i x Int
>     bar :: Monad (IM i x) => IM i x Int -> IM i x Bool
>     cast :: IM i x a -> IM i y a
>
> data Window
>
> instance Impl IO where
>     newtype IM IO x a = IMIO (IO a)
>     foo = IMIO . return
>     bar (IMIO x) = IMIO (fmap (> 42) x)
>     cast (IMIO x) = IMIO x
>
> test :: (Monad (IM i Window), Impl i) => IM i Window Int -> IM i x Bool
> test = cast . bar

Perhaps this isn't what you had in mind; I more elaborate example
would help then.



More information about the Haskell-Cafe mailing list