<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <br>
    <div class="moz-cite-prefix">On 2018-05-16 04:09, Anthony Clayden
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAM7nRYSkD_7+qV9ZEzAoE+e9H13kwinqP_A5B3NSRP8SoQOEAw@mail.gmail.com">
      <div dir="auto">Haskell 98/2010 keeps a strict distinction between
        term-level syntax and tokens vs type-level.</div>
      <div dir="auto"><br>
      </div>
      <div dir="auto">With ExplicitTypeApplications that's being eased:
        there's a lightweight way to sneak a type expression into a
        term. And ghc's internal term language 'core' has had explicit
        type applications for many years.</div>
      <div dir="auto"><br>
      </div>
      <div dir="auto">Then consider a lightweight syntax using type
        applications in patterns to define typeclass instances by
        (pattern) 'matching' on types:</div>
      <div dir="auto"><br>
      </div>
      <div dir="auto">> (==) @Int x y = primEqInt x y         -- or
        eta-reduced</div>
      <div dir="auto">> (==) @Int     = primEqInt             --
        shorthand for</div>
      <div dir="auto">></div>
      <div dir="auto">> instance Eq Int where</div>
      <div dir="auto">>   (==) = primEqInt</div>
      <div dir="auto"><br>
      </div>
      <div dir="auto">Given that many typeclasses have a single method
        (or one base method with others defined in terms of it) [Note
        **], having to invent a typeclass name is a bit of a pain.
        Here's a lighweight method decl:</div>
      <div dir="auto"><br>
      </div>
      <div dir="auto">> meth :: @a @b. => a -> b -> Bool    
         -- typevar binding to left of => (there might also be
        superclass constraints)</div>
      <div dir="auto">>                                       --
        shorthand for</div>
      <div dir="auto">></div>
      <div dir="auto">> class Classfor_meth a b where         --
        generated class name</div>
      <div dir="auto">>   meth :: a -> b -> Bool</div>
    </blockquote>
    <br>
    <p>As Oleg Kiselyov pointed out over a decade ago, all typeclasses
      can be reduced to just one, namely [1]</p>
    <pre> class C l t | l -> t where ac :: l -> t</pre>
    <p>Which in turn is basically an untagged version of the <tt>HasField</tt>
      typeclass that's being used to create overloaded records. [2]</p>
    <div class="highlight highlight-source-haskell">
      <pre><span class="pl-k">    class</span> <span class="pl-en">HasField</span> (<span class="pl-smi">x</span> <span class="pl-k">::</span> <span class="pl-smi">k</span>) <span class="pl-smi">r</span> <span class="pl-smi">a</span> <span class="pl-k">|</span> <span class="pl-smi">x</span> <span class="pl-smi">r</span> <span class="pl-k">-></span> <span class="pl-smi">a</span> <span class="pl-k">where</span> <span class="pl-en">getField</span> <span class="pl-k">::</span> <span class="pl-smi">r</span> <span class="pl-k">-></span> <span class="pl-smi">a</span></pre>
    </div>
    <p>(Not very surprising, because classes are basically compile-time
      records)</p>
    <p>In other words</p>
    <ol>
      <li>You only have one class to replace (left as an exercise to the
        reader)<br>
      </li>
      <li>I don't think you need any fancy new tricks or syntax for
        multi-function classes</li>
      <li>You might be able to also implement records with just type
        application and type families<br>
      </li>
    </ol>
    <p>Cheers,<br>
      MarLinn<br>
    </p>
    <p>[1] <a class="moz-txt-link-freetext" href="http://okmij.org/ftp/Haskell/Haskell1/Haskell1.txt">http://okmij.org/ftp/Haskell/Haskell1/Haskell1.txt</a><br>
      [2]
<a class="moz-txt-link-freetext" href="https://github.com/adamgundry/ghc-proposals/blob/overloaded-record-fields/proposals/0000-overloaded-record-fields.rst#hasfield-class">https://github.com/adamgundry/ghc-proposals/blob/overloaded-record-fields/proposals/0000-overloaded-record-fields.rst#hasfield-class</a><br>
    </p>
  </body>
</html>