<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>