I&#39;m developing a type constructor class and want the constraint <span style="font-family: courier new,monospace;">forall a. Monoid (m a)</span> (where <span style="font-family: courier new,monospace;">m :: * -&gt; *</span>
), which is neither legal Haskell, nor supported by GHC.<br><br>As a work-around, I used the first encoding suggested in &quot;Simulating Quantified Class Constraints&quot; (Valery Trifonov, Haskell Workshop &#39;03).&nbsp; Add a type class
<br><br><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; class Monoid_f m where</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mempty_f&nbsp; :: forall a. m a
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mappend_f :: forall a. m a -&gt; m a -&gt; m a</span><br><br>and an instance *schema*<br><br><span style="font-family: courier new,monospace;">
&nbsp;&nbsp;&nbsp; -- instance Monoid_f f where { mempty_f = mempty ; mappend_f = mappend }</span><br><br>to instantiate manually wherever necessary. For instance,<br><br><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; instance Monoid_f [] where { mempty_f = mempty ; mappend_f = mappend }
</span><br><br><br>The paper&#39;s second approach is to replace the schema and multiple instantiations with a single instance.<br><br><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; instance Monoid_f f =&gt; Monoid (f a) where
</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { mempty = mempty_f ; mappend = mappend_f }</span><br><br>As the paper points out,<br><br><blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote">
Unfortunately, due to the type variable f in the head of the instance type, this declaration is not in Haskell 98; however, at least two implementations support extensions allowing such declarations.<br></blockquote><br>Sadly, this solution runs into the problem of instance selection based only on head-matching, not back-chaining into constraints.&nbsp; For instance, I&#39;d like also to use the following &quot;conflicting&quot; declaration.
<br><br><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; instance (Applicative f, Monoid a) =&gt; Monoid (f a) where </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mempty&nbsp; = pure mempty</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mappend = liftA2 mappend</span><br><br>What&#39;s the state of thinking &amp; doing with regard to universally quantified class constraints?
<br><br>Note that hereditary Harrop formulas do include universally quantified goals.&nbsp; Less ambitiously, I think GHC&#39;s type-checker already deals with universally-quantified variables, so perhaps quantified constraints are not a great reach (just guessing).
<br><br>&nbsp; Cheers,&nbsp; - Conal<br><br>