Hi,
I'm playing around with associated type synonyms (ATS) [1] and the
PHRaC interpreter, trying to model existing uses of FDs. I really
enjoy working with ATS, but I've come across a situation that I don't
quite know how to handle, or indeed if it can be handled at all.
The scene is Control.Monad.Writer from mtl, where we can find the
following definition (simplified for presentation):
class (Monoid w, Monad m) => MonadWriter m w | m -> w where
tell :: w -> m ()
The class MonadWriter has two type parameters, one for the monad
itself and the other for that which is written. The Monoid constraint
on the output is (I guess) there only as a documentation of sorts,
stating that the intention is that the output of subsequent tell's
should be combinable using mplus.
A simple custom monad that just does output could be written as:
data MyWriterM w a = MyWriterM (a, [w])
instance Monad (MyWriterM w) where
return x = MyWriterM (x, [])
MyWriterM (a, xs) >>= k =
let MyWriterM (b, xs') = k a in MyWriterM (b, xs ++ xs')
instance MonadWriter (MyWriterM w) w where
tell x = MyWriterM ((), [x])
Now, to model this using ATS we would write, ignoring the Monoid
constraint, the following class declaration*:
class Monad m => MonadWriter m where
type Output m
tell :: Output m -> m ()
instance MonadWriter (MyWriterM w) where
type Output m = [w]
tell x = MyWriterM ((), [x])
This works fine, but the obvious question is then, where to put back
the Monoid restriction? This time we want the type Output m to be
constrained, so my naive first guess was to write:
class (Monad m, Monoid (Output m)) => MonadWriter m where ..
but phrac says "illegal context for class MonadWriter: only type
variables can be constrained".
I can't really think of anywhere else to put the restriction, other
than making up an ad hoc class constraint syntax for associated types
like
class Monad m => MonadWriter m where
type (Monoid) Output m
...
My first question is already stated: where do I put the Monoid
constraint? But since I suspect the answer is "you don't", a number of
followup questions spring to mind:
- why not? Apart from possibly having to use some ugly syntax for it,
are there any fundamental reasons why this should not be allowed?
- when looking at the definition of MonadWriter the Monoid constraint
is not strictly necessary, and none of the other mtl monads have
anything similar. Is it the assumption that this kind of constraint is
never really necessary, and thus no support for it is needed for ATS?
Hope someone can shed some light on this matter :-)
Regards,
/Niklas
[1] http://www.cse.unsw.edu.au/~chak/papers/CKP05.html
* Using Haskell syntax instead of the PHRaC equivalent