Thanks for your proposal.<br><br>> It is not clear if the class constraint is really needed.<br><br>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.<br>
The methods will be spreaded over various classes. For instance the class IWindow :<br><br>class IWindow i where<br> withinWindow :: Window -> IM i Window a -> IM i x a<br><br>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.<br>
<br><div class="gmail_quote">2011/3/3 <span dir="ltr"><<a href="mailto:oleg@okmij.org">oleg@okmij.org</a>></span><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="im"><br>
Yves Pare`s wrote:<br>
> I'm working on a library which aims to be a generic interface for 2D<br>
> rendering. To do that, one of my goals is to enable each implementation of<br>
> this interface to run in its own monad (most of the time an overlay to IO),<br>
> thus giving me the following class<br>
><br>
> class (Monad (IM i x)) => Impl i x where<br>
> data IM i x :: * -> *<br>
><br>
> (where IM means Implementation Monad)<br>
><br>
</div><div class="im">> I would like to write something like :<br>
><br>
</div><div class="im">> class (forall x. Monad (IM i x)) => Impl i where<br>
> data IM i :: * -> * -> *<br>
<br>
</div>It is not clear if the class constraint is really needed. As an aside,<br>
a class constraint is perhaps a bit of mis-feature of type classes: it sure<br>
improves convenience by making signatures shorter. But it isn't really<br>
necessary. Perhaps there are other, better ways of achieving the<br>
convenience (the constraint alias proposal comes to mind).<br>
<br>
If we drop the class constraint, we can move Monad (IM i x) as the<br>
constraint on specific methods of the Impl class. The implicit uiniversal<br>
quantification on x is well allowed then. For example:<br>
<br>
> class Impl (i :: * -> *) where<br>
> data IM i :: * -> * -> *<br>
> foo :: Monad (IM i x) => Int -> IM i x Int<br>
> bar :: Monad (IM i x) => IM i x Int -> IM i x Bool<br>
> cast :: IM i x a -> IM i y a<br>
><br>
> data Window<br>
><br>
> instance Impl IO where<br>
> newtype IM IO x a = IMIO (IO a)<br>
> foo = IMIO . return<br>
> bar (IMIO x) = IMIO (fmap (> 42) x)<br>
> cast (IMIO x) = IMIO x<br>
><br>
> test :: (Monad (IM i Window), Impl i) => IM i Window Int -> IM i x Bool<br>
> test = cast . bar<br>
<br>
Perhaps this isn't what you had in mind; I more elaborate example<br>
would help then.<br>
</blockquote></div><br>