On Mon, Jul 25, 2011 at 1:40 PM, Jacques Carette <span dir="ltr">&lt;<a href="mailto:carette@mcmaster.ca">carette@mcmaster.ca</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<u></u>

  
    
  
  <div text="#000000" bgcolor="#ffffff"><div class="im">
    On 25/07/2011 9:55 AM, Edward Kmett wrote:<br>
    <blockquote type="cite">
      <div class="gmail_quote">
        <div>
          <div style="color:rgb(0, 0, 0)">
            <span style="color:rgb(31, 73, 125)">If you have an associative (+), then you can use
              (.*) to multiply by a whole number, </span><span style="color:rgb(31, 73, 125)">I
              currently do fold a method into the Additive class to
              &#39;fake&#39; a LeftModule, but you have to explicitly use it.</span></div>
          <div><font color="#1f497d"><br>
            </font></div>
          <div style="color:rgb(0, 0, 0)"><span style="color:rgb(31, 73, 125)">class
              Additive m =&gt; LeftModule r m</span></div>
          <div style="color:rgb(0, 0, 0)">
            <span style="color:rgb(31, 73, 125)">class LeftModule Whole m =&gt; Additive m</span></div>
          <div style="color:rgb(0, 0, 0)"><span style="color:rgb(31, 73, 125)"><br>
            </span></div>
          <div style="color:rgb(0, 0, 0)"><span style="color:rgb(31, 73, 125)">This
              says that if you have an Additive semigroup, then there
              exists a LeftModule over the whole numbers, and that every
              leftmodule is additive, but there can exist other
              LeftModules than just ones over the whole numbers! </span></div>
          <div style="color:rgb(0, 0, 0)"><span style="color:rgb(31, 73, 125)"><br>
            </span></div>
          <div style="color:rgb(0, 0, 0)"><span style="color:rgb(31, 73, 125)">Given
              LeftModule Integer m, you&#39;d know you have </span><span style="color:rgb(31, 73, 125)">Additive
              m </span><span style="color:rgb(31, 73, 125)">and LeftModule Whole m.</span></div>
          <div style="color:rgb(0, 0, 0)"><span style="color:rgb(31, 73, 125)"><br>
            </span></div>
          <div style="color:rgb(0, 0, 0)"><span style="color:rgb(31, 73, 125)">LeftModule
              Integer m =&gt; LeftModule Whole m &lt;=&gt; Additive m.</span></div>
        </div>
      </div>
    </blockquote>
    <br></div>
    I believe that part of the issue here is that you are using a single
    relation (given by class-level =&gt; ) to model what are actually
    two different relations: a &#39;constructive&#39; inclusion and a &#39;view&#39; (to
    use the terminology from the Specifications community, which is
    clearly what these class definitions are).<br>
    <br>
    Just like inheritance hierarchies fail miserably when you try to
    model more than one single relation, it should not be unsurprising
    that the same thing befalls &#39;=&gt;&#39;, which is indeed a (multi-ary)
    relation.<br>
    <br>
    In my own hierarchy for Algebra, I use two relations.  Slightly
    over-simplifying things, one of them reflects &#39;syntactic&#39; inclusion
    while the other models &#39;semantic&#39; inclusion.  There are very strict
    rules for the &#39;syntactic&#39; one, so that I get a nice hierarchy and
    lots of free theorems, while the semantic one is much freer, but
    generates proof obligations which must be discharged.  The syntactic
    one generates a nice DAG (with lots of harmless diamonds), while the
    semantic one is a fully general graph.<br>
    <br>
    Here is another way to look at it:  when you say<div class="im"><br>
    class LeftModule Whole m =&gt; Additive m<br></div>
    you are closer to specifying an *instance* relation than a *class
    constraint* relation.  </div></blockquote><div><br></div><div>This is very true. </div><div><br></div><div>However, as mentioned at the outset specifying such instance requires newtype noise (on m, to avoid incoherent overlap with the other instances) that leads to a particularly hideous programming style.</div>
<div><br></div><div>newtype NaturalModule m = NaturalModule { runNaturalModule :: m }</div><div><br></div><div>instance Monoidal m =&gt; LeftModule Natural (NaturalModule m) where</div><div><br></div><div>It isn&#39;t so bad when working with simple examples like</div>
<div><br></div><div>fiveTimes m = runNaturalModule (5 .* NaturalModule m)</div><div><br></div><div>but it gets progressively worse as the hierarchy gets deeper, and I have to deal with putting on and taking off more and more of these silly wrappers.</div>
<div><br></div><div>Placing the superclass constraint enforces that such instances will always be available to me, and admits optimized implementations, which I currently have to shoehorn into the main class and expose by convention.</div>
<div><br></div><div>-Edward</div></div>