<div dir="ltr"><div><font face="arial, helvetica, sans-serif">Here's a typical simple type error from GHC:</font></div><div style="font-family:monospace,monospace"><font face="monospace, monospace"><br></font></div><font face="monospace, monospace">Derive/Call/India/Pakhawaj.hs:142:62:</font><br><font face="monospace, monospace">    Couldn't match type ‘Text’ with ‘(a1, Syllable)’</font><br><font face="monospace, monospace">    Expected type: [([(a1, Syllable)], [Sequence Bol])]</font><br><font face="monospace, monospace">      Actual type: [([Syllable], [Sequence Bol])]</font><br><font face="monospace, monospace">    Relevant bindings include</font><br><font face="monospace, monospace">      syllables :: [(a1, Syllable)]</font><br><font face="monospace, monospace">        (bound at Derive/Call/India/Pakhawaj.hs:141:16)</font><br><font face="monospace, monospace">      best_match :: [(a1, Syllable)]</font><br><font face="monospace, monospace">                    -> Maybe (Int, ([(a1, Syllable)], [(a1, Sequence Bol)]))</font><br><font face="monospace, monospace">        (bound at Derive/Call/India/Pakhawaj.hs:141:5)</font><br><font face="monospace, monospace">    In the second argument of ‘mapMaybe’, namely ‘all_bols’</font><br><font face="monospace, monospace">    In the second argument of ‘($)’, namely</font><br><font face="monospace, monospace">      ‘mapMaybe (match_bols syllables) all_bols’</font><br><br><font face="arial, helvetica, sans-serif">I've been having more trouble than usual reading GHC's errors, and I finally spent some time to think about it.  The problem is that this new "relevant bindings include" section gets in between the expected and actual types (I still don't like that wording but I've gotten used to it), which is the most critical part, and the location context, which is second most critical.  Notice the same effect in the previous sentence :)  After I see a type error the next thing I want to see is the where it happened, so I have to skip over the bindings, which can be long and complicated.  Then I usually know what to do, and only look into the bindings if something more complicated is going on, like wonky inference.  So how about reordering the message:</font><br><br><font face="monospace, monospace">Derive/Call/India/Pakhawaj.hs:142:62:</font><br><font face="monospace, monospace">    Couldn't match type ‘Text’ with ‘(a1, Syllable)’</font><br><font face="monospace, monospace">    Expected type: [([(a1, Syllable)], [Sequence Bol])]</font><br><font face="monospace, monospace">      Actual type: [([Syllable], [Sequence Bol])]</font><br><font face="monospace, monospace">    In the second argument of ‘mapMaybe’, namely ‘all_bols’</font><br><font face="monospace, monospace">    In the second argument of ‘($)’, namely</font><br><font face="monospace, monospace">      ‘mapMaybe (match_bols syllables) all_bols’</font><br><font face="monospace, monospace">    Relevant bindings include</font><br><font face="monospace, monospace">      syllables :: [(a1, Syllable)]</font><br><font face="monospace, monospace">        (bound at Derive/Call/India/Pakhawaj.hs:141:16)</font><br><font face="monospace, monospace">      best_match :: [(a1, Syllable)]</font><br><font face="monospace, monospace">                    -> Maybe (Int, ([(a1, Syllable)], [(a1, Sequence Bol)]))</font><br><font face="monospace, monospace">        (bound at Derive/Call/India/Pakhawaj.hs:141:5)</font><br><br><font face="arial, helvetica, sans-serif">After this, why not go one step further and set off the various sections visibly to make it easier to scan.  The context section can also be really long if it gets an entire do block or record:</font><br><br><font face="monospace, monospace">Derive/Call/India/Pakhawaj.hs:142:62:</font><br><font face="monospace, monospace">  * Couldn't match type ‘Text’ with ‘(a1, Syllable)’</font><br><font face="monospace, monospace">    Expected type: [([(a1, Syllable)], [Sequence Bol])]</font><br><font face="monospace, monospace">      Actual type: [([Syllable], [Sequence Bol])]</font><br><font face="monospace, monospace">  * In the second argument of ‘mapMaybe’, namely ‘all_bols’</font><br><font face="monospace, monospace">    In the second argument of ‘($)’, namely</font><br><font face="monospace, monospace">      ‘mapMaybe (match_bols syllables) all_bols’</font><br><font face="monospace, monospace">  * Relevant bindings include</font><br><font face="monospace, monospace">      syllables :: [(a1, Syllable)]</font><br><font face="monospace, monospace">        (bound at Derive/Call/India/Pakhawaj.hs:141:16)</font><br><font face="monospace, monospace">      best_match :: [(a1, Syllable)]</font><br><font face="monospace, monospace">                    -> Maybe (Int, ([(a1, Syllable)], [(a1, Sequence Bol)]))</font><br><font face="monospace, monospace">        (bound at Derive/Call/India/Pakhawaj.hs:141:5)</font><div><font face="monospace, monospace"><br></font></div><div><font face="arial, helvetica, sans-serif">Or alternately, taking up a bit more vertical space:</font></div><div><font face="monospace, monospace"><br></font></div><div><span style="font-family:monospace,monospace">Derive/Call/India/Pakhawaj.hs:142:62:</span><br style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">    Couldn't match type ‘Text’ with ‘(a1, Syllable)’</span><br style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">    Expected type: [([(a1, Syllable)], [Sequence Bol])]</span><br style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">      Actual type: [([Syllable], [Sequence Bol])]</span></div><div>        -----------------------------<br style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">    In the second argument of ‘mapMaybe’, namely ‘all_bols’</span><br style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">    In the second argument of ‘($)’, namely</span><br style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">      ‘mapMaybe (match_bols syllables) all_bols’</span></div><div>        -----------------------------<br style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">    Relevant bindings include</span></div><div><span style="font-family:monospace,monospace">      syllables :: [(a1, Syllable)]</span><br style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">        (bound at Derive/Call/India/Pakhawaj.hs:141:16)</span><br style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">      best_match :: [(a1, Syllable)]</span><br style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">                    -> Maybe (Int, ([(a1, Syllable)], [(a1, Sequence Bol)]))</span><br style="font-family:monospace,monospace"><span style="font-family:monospace,monospace">        (bound at Derive/Call/India/Pakhawaj.hs:141:5)</span><br style="font-family:monospace,monospace"></div><div><span style="font-family:monospace,monospace"><br></span></div><div><font face="arial, helvetica, sans-serif">Thoughts?  It seems simple enough that I could do myself, but of course not without buy-in.</font></div></div>