<div dir="ltr"><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font face="arial, sans-serif"><br class="gmail-Apple-interchange-newline">
> ... I never understood why (->) is right associative in types, but (=>) is not and you are instead supposed to pack constraints in a tuple.
</font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font face="arial, sans-serif"><br></font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font face="arial, sans-serif">`-XRankNTypes` enables something called Rank 1 types, which accepts this:</font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font face="arial, sans-serif"><br></font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font face="arial, sans-serif">> foo :: Ord a => Num b => a -> Show b => b</font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font face="arial, sans-serif">> -- foo :: (Ord a, Num b, Show b) => a -> b -- inferred/canonical</font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font face="arial, sans-serif"><br></font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font face="arial, sans-serif">We should also have:</font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font face="arial, sans-serif"><br></font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font face="arial, sans-serif">> bar :: forall a. forall {- empty -}. forall b. blah</font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font face="arial, sans-serif">> -- bar :: forall a b. blah -- equivalent</font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font face="arial, sans-serif"><br></font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font face="arial, sans-serif">But `PatternSynonyms` drives a cart and horses through that: you must have exactly 2 `... => ... => ...` and exactly 2 `forall`s (possibly empty) -- that is, if you explicitly quantify at all. Or you can go:</font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font face="arial, sans-serif"><br></font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font face="arial, sans-serif">> MyPat :: Num a => a -> Baz a -- which is shorthand for</font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font face="arial, sans-serif">> MyPat :: Num a => () => a -> Baz a -- which is equiv to</font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font face="arial, sans-serif">> MyPat :: Num a => Num a => a -> Baz a</font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font face="arial, sans-serif">> MyPat :: () => Num a => a -> Baz a -- this means something different</font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><font face="arial, sans-serif"><br></font></pre><pre style="white-space:pre-wrap;color:rgb(0,0,0)"><br></pre></div>