My situation is fairly similar to Gabor&#39;s, and, like him, I was able to make do with an equality superclass.  However, instead of combining two classes, I found that I needed to add a third.<div><br></div><div>My concept here is to create two monads which share much of their functionality, but not all of it.  Specifically, one of them is &quot;high&quot; and one is &quot;low&quot;.  Values of type &quot;Low&quot; encapsulate computations in the low monad, and values of type &quot;High&quot; encapsulate values in the high monad.  Both low and high monads can *create* Low and High values and *execute* Low values, but only the high monad can *execute* High values.</div>
<div><br></div><div>So, what I&#39;d like to write is:</div><div><div><br></div><div>data High a</div><div><br></div><div>data Low a</div></div><div><br></div><div><div>class (Monad m, MonadLow (LowM m), MonadHigh (HighM m)) =&gt; MonadLow m where</div>
<div>  execLow :: Low a -&gt; m a</div><div>  type LowM m :: * -&gt; *</div><div>  mkLow :: LowM m a -&gt; m (Low a)</div><div>  type HighM m :: * -&gt; *</div><div>  mkHigh :: HighM m a -&gt; m (High a)</div><div><br></div>
<div>class MonadLow m =&gt; MonadHigh m where</div><div>  execHigh :: High a -&gt; m a</div><div><br></div><div>data L a</div><div><br></div><div>data H a</div><div><br></div><div>instance Monad L</div><div><br></div><div>
instance MonadLow L where</div><div>    type LowM L = L</div><div>    type HighM L = H</div><div><br></div><div>instance Monad H</div><div><br></div><div>instance MonadLow H where</div><div>    type LowM H = L</div><div>    type HighM H = H</div>
<div><br></div><div>instance MonadHigh H</div><div><br></div><div>Of course, this has a superclass cycle.  Instead, I can write:</div><div><br></div><div>...</div><div>class Monad m =&gt; MonadLow m where</div><div>...</div>
<div>class (MonadHigh m, MonadLow (LowM m), HighM m ~ m, HighM (LowM m) ~ m, LowM (LowM m) ~ LowM m) =&gt; MonadHigh&#39; m where {}</div><div><br></div><div>Then I can use MonadHigh&#39; wherever I might have instead used MonadHigh, and achieve roughly the result I was looking for.  However, it doesn&#39;t seem like a very clean definition to me.</div>
<div><br></div><div>That being said, I haven&#39;t found any problem with using the MonadHigh&#39; approach, although I&#39;ve just recently started investigating it.</div><div><br></div><div><br></div><div>Ryan</div><div>
<br></div><br><div class="gmail_quote">2011/7/22 Dan Doel <span dir="ltr">&lt;<a href="mailto:dan.doel@gmail.com">dan.doel@gmail.com</a>&gt;</span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
2011/7/22 Gábor Lehel &lt;<a href="mailto:illissius@gmail.com">illissius@gmail.com</a>&gt;:<br>
<div class="im">&gt; Yeah, this is pretty much what I ended up doing. As I said, I don&#39;t<br>
&gt; think I lose anything in expressiveness by going the MPTC route, I<br>
&gt; just think the two separate but linked classes way reads better. So<br>
&gt; it&#39;s just a &quot;would be nice&quot; thing. Do recursive equality superclasses<br>
&gt; make sense / would they be within the realm of the possible to<br>
&gt; implement?<br>
<br>
</div>Those equality superclasses are not recursive in the same way, as far<br>
as I can tell. The specifications for classes require that there is no<br>
chain:<br>
<br>
    C ... =&gt; D ... =&gt; E ... =&gt; ... =&gt; C ...<br>
<br>
However, your example just had (~) as a context for C, but C is not<br>
required by (~). And the families involved make no reference to C,<br>
either. A fully desugared version looks like:<br>
<br>
    type family Frozen a :: *<br>
    type family Thawed a :: *<br>
<br>
    class (..., Thawed (Frozen t) ~ t) =&gt; Mutable t where ...<br>
<br>
I think this will be handled if you use a version where equality<br>
superclasses are allowed.<br>
<font color="#888888"><br>
-- Dan<br>
</font><div><div></div><div class="h5"><br>
_______________________________________________<br>
Glasgow-haskell-users mailing list<br>
<a href="mailto:Glasgow-haskell-users@haskell.org">Glasgow-haskell-users@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/glasgow-haskell-users" target="_blank">http://www.haskell.org/mailman/listinfo/glasgow-haskell-users</a><br>
</div></div></blockquote></div><br></div>