<div dir="auto">(More from the annals of oh-so-easy in yacc.)</div><div dir="auto"><br></div><div>On Thu, 4 Oct 2018 at 12:45 AM, Anthony Clayden <<a href="mailto:anthony_clayden@clear.net.nz">anthony_clayden@clear.net.nz</a>> wrote:<br></div><div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto">A typical consequence of combining FunDeps + Overlapping instances is that you have to make the result parameter more general than it needs be, then use a TypeCast constraint to improve it.</div><div dir="auto"><br></div><div dir="auto">... TypeCast, which does use FunDeps to mutually improve/unify its two parameters. Nowadays in GHC you'd use the (~) constraint.</div></blockquote><div dir="auto"><br></div><div dir="auto">I got so fed up writing out TypeCast constraints; and I'm so used to writing infix (~) in GHC, I implemented (~) in Hugs. This is hard-coded syntax in constraints; I've not implemented type operators. (Mark you, it's also hard-coded in GHC, because (~) is a reserved symbol.)</div><div dir="auto"><br></div><div dir="auto">This needed only changes to the yacc syntax. From that I insisted that "~" is a legitimate name for a class. There is a downside that equality constraints are printed with the '~' prefix -- because all class names are prefix.</div><div dir="auto"><br></div><div dir="auto">To be clear: this is not as powerful or well-integrated as (~) in GHC. You still need at the term level to explicitly cast.</div><div dir="auto"><br></div><div dir="auto">Then I got so fed up writing out explicit typeCast calls ..., I picked up the postfix operators idea</div><div dir="auto"><div><a href="https://mail.haskell.org/pipermail/hugs-users/2018-September/000909.html">https://mail.haskell.org/pipermail/hugs-users/2018-September/000909.html</a></div>and invented a postfix operator (~::) to do the job.</div><div dir="auto">Trailing double-colon says I'm doing something typeful; tilde connects it to the equality constraint.</div><div dir="auto"><br></div><div dir="auto">Then here's the classic, compiled in Hugs, also exhibiting the FunDeps + Overlaps combo</div><div dir="auto"><br></div><div dir="auto">class TypeEq t t' r  | t t' -> r  where</div><div dir="auto">  typeEq :: t -> t' -> r</div><div dir="auto"><br></div><div dir="auto">instance TypeEq t t TTrue  where</div><div dir="auto">  typeEq _ _ = TTrue</div><div dir="auto"><br></div><div dir="auto">instance (TFalse ~ f) => TypeEq t t' f  where</div><div dir="auto">  typeEq _ _ = (TFalse ~::)      -- without explicit cast, complains type is not general enough</div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto">AntC</div></div></div>