[Haskell-cafe] Rank-2 types in classes

Yves Parès limestrael at gmail.com
Thu Mar 3 10:13:52 CET 2011


Thanks for your proposal.

> It is not clear if the class constraint is really needed.

Well 'IM' means 'ImplementationMonad', so it wouldn't make much sense if an
IM of an implementation wasn't also a monad. And since IM is the central
monad of the library, a lot of functions will use IM.
The methods will be spreaded over various classes. For instance the class
IWindow :

class IWindow i where
    withinWindow :: Window -> IM i Window a -> IM i x a

So a method like 'cast' shouldn't exist, since it would allow the user to
switch the context freely. Methods like withinWindow will do that, but
safely.

2011/3/3 <oleg at okmij.org>

>
> 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.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20110303/4b588797/attachment.htm>


More information about the Haskell-Cafe mailing list