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.
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 whereIt is not clear if the class constraint is really needed. As an aside,
> data IM i :: * -> * -> *
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.