<div dir="ltr"><div>The problem's not solved! Check out this weirdness. |+| and |-| are supposed to be identical, mapping to the same function, the Pair constructor.</div><div><br></div><div>    > mapM_ putStrLn exprs</div><div>    a |+| b</div><div>    a |-| b</div><div>    a |+| b |-| c</div><div>    a |-| b |+| c</div><div>    a |+| b   |-|  c |+| d</div><div>    > mapM_ putStrLn $ map (show . parseMaybe aExpr) exprs</div><div>    Just (Pair (Var "a") (Var "b"))</div><div>    Nothing</div><div>    Just (Pair (Pair (Var "a") (Var "b")) (Var "c"))</div><div>    Nothing</div><div>    Just (Pair (Pair (Var "a") (Var "b")) (Pair (Var "c") (Var "d")))</div><div><br></div><div>Why the two failures?</div><div><br></div><div>If I change them from InfixN to InfixR or InfixL, then only the first of those five expressions parses.</div><div><br></div><div>Here are two relevant definitions:</div><div><br></div><div>    data AExpr = Var String | Pair AExpr AExpr deriving (Show)</div><div><br></div><div>    aOperators :: [[Operator Parser AExpr]]</div><div>    aOperators =</div><div>      [ [ InfixN $ symbol "|+|" *> pure (Pair) ]</div><div>      , [ InfixN $ symbol "|-|" *> pure (Pair) ] -- binds last, I think</div><div>      ]</div><div><br></div><div>And here is the code in full[1].</div><div><br></div><div>Thanks,</div><div>Jeff</div><div><br></div><div><br></div><div>[1] <a href="https://github.com/JeffreyBenjaminBrown/digraphs-with-text/blob/master/howto/megaparsec/minimal.hs">https://github.com/JeffreyBenjaminBrown/digraphs-with-text/blob/master/howto/megaparsec/minimal.hs</a></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Oct 23, 2016 at 2:50 PM, Brandon Allbery <span dir="ltr"><<a href="mailto:allbery.b@gmail.com" target="_blank">allbery.b@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Aha. I had forgotten some details.<div><br></div><blockquote style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex" class="gmail_quote"><span style="color:rgb(0,0,0);font-family:sans-serif;font-size:13px">If you want to have an operator that is a prefix of another operator in the table, use the following (or similar) wrapper instead of plain </span><code style="margin:0px;padding:0px;line-height:16.12px;color:rgb(0,0,0);font-size:13px">symbol</code><span style="color:rgb(0,0,0);font-family:sans-serif;font-size:13px">:<br></span>op n = (lexeme . try) (string n <* notFollowedBy punctuationChar)</blockquote><div class="gmail_extra"><a href="http://hackage.haskell.org/package/megaparsec-5.1.1/docs/Text-Megaparsec-Expr.html#v:makeExprParser" target="_blank">http://hackage.haskell.org/<wbr>package/megaparsec-5.1.1/docs/<wbr>Text-Megaparsec-Expr.html#v:<wbr>makeExprParser</a><br></div><div class="gmail_extra"><br></div><div class="gmail_extra">So you actually need to be a little clever for those two operators to work; it's not as simple as I had recalled it (which would have been correct for a basic manual combinator setup). I am going to guess that something in there is not using `try` and silently consuming the extra "#", but I'd have to study the `makeExprParser` code in Megaparsec to be certain.</div><div><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Oct 23, 2016 at 5:38 PM, Jeffrey Brown <span dir="ltr"><<a href="mailto:jeffbrown.the@gmail.com" target="_blank">jeffbrown.the@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Thanks, Brandon! How did you know that?<div><br></div><div>I changed them to "#1" and "#2" and now it works[1].</div><div><br></div><div>But before making that change, why would "a # b ## c # d" evaluate, even though "a ## b" would not?</div><div><br></div><div><br></div><div><div>[1] <a href="https://github.com/JeffreyBenjaminBrown/digraphs-with-text/tree/master/howto/megaparsec" target="_blank">https://github.com/JeffreyBenj<wbr>aminBrown/digraphs-with-text/<wbr>tree/master/howto/megaparsec</a></div><div>The corrected file is called "experim.hs"; the old one, uncorrected, is called "experim.buggy.hs".</div></div></div><div class="gmail_extra"><div><div class="m_7166847740138124910gmail-h5"><br><div class="gmail_quote">On Sun, Oct 23, 2016 at 2:03 PM, Brandon Allbery <span dir="ltr"><<a href="mailto:allbery.b@gmail.com" target="_blank">allbery.b@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><span><br><div class="gmail_quote">On Sun, Oct 23, 2016 at 4:15 PM, Jeffrey Brown <span dir="ltr"><<a href="mailto:jeffbrown.the@gmail.com" target="_blank">jeffbrown.the@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><font face="monospace, monospace">      [ [ InfixN # symbol "#" *> pure (Pair) ]</font></div><div><font face="monospace, monospace">      , [ InfixN # symbol "##" *> pure (Pair) ]</font></div><div><font face="monospace, monospace">      ]</font></div></blockquote></div><div class="gmail_extra"><br></div></span>Combinator parsers can't rearrange themselves to do longest token matching. So the ## operator will take the first case, match against `symbol "#"` and aOperator will succeed; the the next token match will hit the unconsumed "#" and fail. If you place "##" first then it will match "##" but not "#", which would the match the second rule.</div><span class="m_7166847740138124910gmail-m_-2508914328058768703HOEnZb"><font color="#888888"><div class="gmail_extra"><div><br></div>-- <br><div class="m_7166847740138124910gmail-m_-2508914328058768703m_1643006919693412385gmail_signature"><div dir="ltr"><div>brandon s allbery kf8nh                               sine nomine associates</div><div><a href="mailto:allbery.b@gmail.com" target="_blank">allbery.b@gmail.com</a>                                  <a href="mailto:ballbery@sinenomine.net" target="_blank">ballbery@sinenomine.net</a></div><div>unix, openafs, kerberos, infrastructure, xmonad        <a href="http://sinenomine.net" target="_blank">http://sinenomine.net</a></div></div></div>
</div></font></span></div>
</blockquote></div><br><br clear="all"><div><br></div></div></div><span class="m_7166847740138124910gmail-">-- <br><div class="m_7166847740138124910gmail-m_-2508914328058768703gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>Jeff Brown | Jeffrey Benjamin Brown</div><div dir="ltr"><a href="https://msu.edu/~brown202/" style="font-size:12.8px" target="_blank">Website</a>   |   <a href="https://www.facebook.com/mejeff.younotjeff" style="font-size:12.8px" target="_blank">Facebook</a>   |   <a href="https://www.linkedin.com/in/jeffreybenjaminbrown" style="font-size:12.8px" target="_blank">LinkedIn</a><span style="font-size:12.8px">(I often miss messages here)   |   </span><a href="https://github.com/jeffreybenjaminbrown" style="font-size:12.8px" target="_blank">Github</a></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div>
</span></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="m_7166847740138124910gmail_signature"><div dir="ltr"><div>brandon s allbery kf8nh                               sine nomine associates</div><div><a href="mailto:allbery.b@gmail.com" target="_blank">allbery.b@gmail.com</a>                                  <a href="mailto:ballbery@sinenomine.net" target="_blank">ballbery@sinenomine.net</a></div><div>unix, openafs, kerberos, infrastructure, xmonad        <a href="http://sinenomine.net" target="_blank">http://sinenomine.net</a></div></div></div>
</div></div></div></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>Jeff Brown | Jeffrey Benjamin Brown</div><div dir="ltr"><a href="https://msu.edu/~brown202/" style="font-size:12.8px" target="_blank">Website</a>   |   <a href="https://www.facebook.com/mejeff.younotjeff" style="font-size:12.8px" target="_blank">Facebook</a>   |   <a href="https://www.linkedin.com/in/jeffreybenjaminbrown" style="font-size:12.8px" target="_blank">LinkedIn</a><span style="font-size:12.8px">(spammy, so I often miss messages here)   </span><span style="font-size:12.8px">|</span><span style="font-size:12.8px">   </span><a href="https://github.com/jeffreybenjaminbrown" style="font-size:12.8px" target="_blank">Github</a><span style="font-size:12.8px">   </span></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div>
</div>