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