<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">`try` won't work for me, as the next alternative would be `eof`, if the non-essential parts of input are not consumed, `eof` won't match.<div class=""><br class=""></div><div class="">The line for the MWE at <a href="https://github.com/complyue/dcp/blob/91616496e43d153ca8ae92c0d030b3cdc351fb6c/src/Parser.hs#L136" class="">https://github.com/complyue/dcp/blob/91616496e43d153ca8ae92c0d030b3cdc351fb6c/src/Parser.hs#L136</a></div><div class=""><br class=""></div><div class="">```hs</div><div class=""><div style="color: rgb(212, 190, 152); background-color: rgb(23, 24, 24); font-family: Menlo, Monaco, "Courier New", monospace; line-height: 18px; white-space: pre;" class=""><div class=""><span style="color: #d4bfa0;" class="">  arts    </span><span style="color: #cc524b;font-weight: bold;" class=""><-</span><span style="color: #d4bfa0;" class=""> manyTill </span>(<span style="color: #d4bfa0;" class="">scWithSemiColons </span><span style="color: #a3d349;" class="">>></span><span style="color: #d4bfa0;" class=""> artifactDecl</span>)<span style="color: #d4bfa0;" class=""> eof</span></div><div class=""><span style="color: #d4bfa0;" class=""></span></div></div></div><div class="">```<br class=""><div><br class=""></div><div>And the artifact parser <a href="https://github.com/complyue/dcp/blob/91616496e43d153ca8ae92c0d030b3cdc351fb6c/src/Parser.hs#L139-L147" class="">https://github.com/complyue/dcp/blob/91616496e43d153ca8ae92c0d030b3cdc351fb6c/src/Parser.hs#L139-L147</a></div><div><br class=""></div><div>```hs</div><div><div style="color: rgb(212, 190, 152); background-color: rgb(23, 24, 24); font-family: Menlo, Monaco, "Courier New", monospace; line-height: 18px; white-space: pre;" class=""><div class=""><span style="color: #66a89d;" class="">artifactDecl</span><span style="color: #96b946;" class=""> </span><span style="color: #cc524b;font-weight: bold;" class="">::</span><span style="color: #96b946;" class=""> </span><span style="color: #6b95c5;" class="">Parser</span><span style="color: #96b946;" class=""> </span><span style="color: #6b95c5;" class="">ArtDecl</span></div><div class=""><span style="color: #d4bfa0;" class="">artifactDecl </span><span style="color: #cc524b;font-weight: bold;" class="">=</span><span style="color: #d4bfa0;" class=""> lexeme </span><span style="color: #a3d349;" class="">$</span><span style="color: #d4bfa0;" class=""> </span><span style="color: #cc524b;" class="">do</span></div><div class=""><span style="color: #d4bfa0;" class="">  artCmt </span><span style="color: #cc524b;font-weight: bold;" class=""><-</span><span style="color: #d4bfa0;" class=""> optional immediateDocComment</span></div><div class=""><span style="color: #d4bfa0;" class="">  </span>(<span style="color: #d4bfa0;" class="">eof </span><span style="color: #a3d349;" class="">>></span><span style="color: #d4bfa0;" class=""> empty</span>)<span style="color: #d4bfa0;" class=""> </span><span style="color: #a3d349;" class=""><|></span><span style="color: #d4bfa0;" class=""> </span><span style="color: #cc524b;" class="">do</span></div><div class=""><span style="color: #d4bfa0;" class="">    artBody </span><span style="color: #cc524b;font-weight: bold;" class=""><-</span><span style="color: #d4bfa0;" class=""> takeWhileP </span>(<span style="color: #cca143;" class="">Just</span><span style="color: #d4bfa0;" class=""> </span><span style="color: #97a2a7;" class="">"artifact body"</span>)</div><div class=""><span style="color: #d4bfa0;" class="">                          </span>(<span style="color: #d4bfa0;" class="">not </span><span style="color: #a3d349;" class="">.</span><span style="color: #d4bfa0;" class=""> flip elem </span>(<span style="color: #97a2a7;" class="">";{"</span><span style="color: #d4bfa0;" class=""> </span><span style="color: #cc524b;font-weight: bold;" class="">::</span><span style="color: #d4bfa0;" class=""> </span>[<span style="color: #6b95c5;" class="">Char</span>]))</div><div class=""><span style="color: #d4bfa0;" class="">    </span><span style="color: #cc524b;" class="">if</span><span style="color: #d4bfa0;" class=""> </span><span style="color: #73a36c;" class="">T.</span><span style="color: #d4bfa0;" class="">null </span><span style="color: #a3d349;" class="">$</span><span style="color: #d4bfa0;" class=""> </span><span style="color: #73a36c;" class="">T.</span><span style="color: #d4bfa0;" class="">strip artBody</span></div><div class=""><span style="color: #d4bfa0;" class="">      </span><span style="color: #cc524b;" class="">then</span><span style="color: #d4bfa0;" class=""> empty </span><span style="color: #7e6b5f;" class="">-- this is not possible in real cases</span></div><div class=""><span style="color: #d4bfa0;" class="">      </span><span style="color: #cc524b;" class="">else</span><span style="color: #d4bfa0;" class=""> return </span>(<span style="color: #d4bfa0;" class="">artCmt</span>,<span style="color: #d4bfa0;" class=""> artBody</span>)</div><br class=""></div></div><div>```</div><div><br class=""></div><div>The `<span style="font-family: Menlo, Monaco, "Courier New", monospace; white-space: pre; color: rgb(212, 191, 160);" class="">eof </span><span style="font-family: Menlo, Monaco, "Courier New", monospace; white-space: pre; color: rgb(163, 211, 73);" class="">>></span><span style="font-family: Menlo, Monaco, "Courier New", monospace; white-space: pre; color: rgb(212, 191, 160);" class=""> empty</span>` in above will cause the parsing to err out overall, because the line before it `<span style="caret-color: rgb(212, 191, 160); color: rgb(212, 191, 160); font-family: Menlo, Monaco, "Courier New", monospace; white-space: pre; background-color: rgb(23, 24, 24);" class="">optional immediateDocComment</span>` has consumed some input.</div><div><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class="">On 2020-10-27, at 23:57, Li-yao Xia <<a href="mailto:lysxia@gmail.com" class="">lysxia@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">That sounds like a use case for "try". Is it not?<br class=""><br class="">Li-yao<br class=""><br class="">On 10/27/2020 11:38 AM, YueCompl wrote:<br class=""><blockquote type="cite" class="">Li-yao, the issue my parser faces is unable to express an recoverable *error*, that though it consumed some whitespaces, it doesn't want to raise an unrecoverable error, `empty` is supposed to do that in my intuition, but Megaparsec considers it an unrecoverable error in this case.<br class="">Best regards,<br class="">Compl<br class=""><blockquote type="cite" class="">On 2020-10-27, at 23:22, Li-yao Xia <<a href="mailto:lysxia@gmail.com" class="">lysxia@gmail.com</a>> wrote:<br class=""><br class="">That law (v >> mzero = mzero) is controversial. It's near impossible to satisfy for slightly sophisticated monads. It's notably broken by `MaybeT` whose very purpose is to augment a monad with such an extra Alternative/MonadPlus capability (a concrete counterexample for that law can be found with `MaybeT (State s)`).<br class=""><br class="">MonadPlus is there mainly for historical reasons, because it predates Applicative. Then Alternative was added because the operations turned out to be useful even for Applicatives that were not Monads. The presence of both seems to sugggest there ought to be a difference, but IMO they should just be considered the same and we should thus simply forget about MonadPlus. How would you document that Alternative and MonadPlus may have different  implementations anyway? Imagine if `Control.Monad.msum` and `Control.Applicative.asum` were not the same, how confusing that would be.<br class=""><br class="">To add an error that can not be recovered from you can use `Maybe` or `Either` as the base monad for `ParsecT`: `ParsecT e s Maybe`, so `lift Nothing` fails with your "unparsable" semantics.<br class=""><br class="">Li-yao<br class=""><br class="">On 10/27/2020 6:33 AM, Jaro Reinders wrote:<br class=""><blockquote type="cite" class="">Yeah, it seems Megaparsecs parser violates the MonadPlus laws:<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">isRight $ parse ((char 'a' >> mzero) `mplus` char 'a') "" "a"<br class=""></blockquote></blockquote></blockquote>False<br class=""><blockquote type="cite" class=""><blockquote type="cite" class=""><blockquote type="cite" class="">isRight $ parse (mzero `mplus` char 'a') "" "a"<br class=""></blockquote></blockquote></blockquote>True<br class="">I've created an issue: <a href="https://github.com/mrkkrp/megaparsec/issues/430" class="">https://github.com/mrkkrp/megaparsec/issues/430</a>.<br class="">On 10/27/20 11:15 AM, YueCompl wrote:<br class=""><blockquote type="cite" class="">Isn't  'u <*> empty = empty' resembles MonadPlus?<br class=""><br class="">mzero >>= f  =  mzero<br class="">v >> mzero   =  mzero<br class=""><br class="">Since ParsecT also has a MonadPlus instance, can we have different implementations of `empty` and `mzero` to have these 2 separate semantics expressible:<br class=""><br class="">*) parse to ignored result from some input<br class="">*) un-parsable (input consumed or not is irrelevant as to err out anyway)<br class=""><br class=""><br class="">parse to no significant result<br class="">unparsable<br class="">consumed input<br class="">empty -> throw ??<br class="">mzero -> throw<br class="">no input consumed<br class="">empty -> nothrow<br class="">mzero -> throw<br class=""><br class="">I'd much like the behavior above `empty -> throw ??` changed to `empty -> nothrow`<br class=""><br class=""><blockquote type="cite" class="">On 2020-10-27, at 17:47, Jaro Reinders <<a href="mailto:jaro.reinders@gmail.com" class="">jaro.reinders@gmail.com</a>> wrote:<br class=""><br class="">The 'empty' value should always be the unit of <|>, that is specified in the documentation of the Alternative class. The problem starts when you build composite parsers. E.g. (char 'a' *> empty) does not need to be a unit of <|>. I thought of 'fixing' this by adding another law 'u <*> empty = empty', but that disregards all effects that u can have.<br class=""><br class="">On 10/27/20 10:26 AM, YueCompl via Haskell-Cafe wrote:<br class=""><blockquote type="cite" class="">In [1], Alternative is said being most commonly considered to form a monoid, so that:<br class="">```hs<br class="">-- empty is a neutral element<br class="">empty <|> u  =  u<br class="">u <|> empty  =  u<br class="">```<br class="">In my particular case wrt Megaparsec, when the artifact parser evaluates to `empty` at eof, I suppose the outer `many` should evaluate to whatsoever previously parsed, but current implementation of Megaparsec makes it conditional:<br class="">*) in case the parser hasn't consumed any input, it works the way as expected<br class="">*) incase the parser has consumed some input (whitespaces), the outer `many` throws error<br class="">So can I say this is a violation regarding [1]?<br class="">Best regards,<br class="">Compl<br class=""><blockquote type="cite" class="">On 2020-10-27, at 04:18, Olaf Klinke <<a href="mailto:olf@aatal-apotheke.de" class="">olf@aatal-apotheke.de</a>> wrote:<br class=""><br class="">I used to think that an Alternative is just an Applicative which is<br class="">also a Monoid but apparently there is no consensus about this [1,2].<br class="">Actually it kind of makes sense to make the 'empty' parser fail:<br class="">Consider the parser combinator<br class=""><br class="">choice = Data.Foldable.asum = foldr (<|>) empty<br class=""><br class="">which folds over a list of Alternatives. Its semantics can be regarded<br class="">analogous to 'any' for a list of Booleans, and in the latter the empty<br class="">list evaluates to False.<br class="">Put differently: The parser (p <|> q) matches at least as many inputs<br class="">than either p or q. Hence the neutral element for <|> ought to be the<br class="">parser that matches the least amount of inputs, but a parser that<br class="">succeeds on the empty string _does_ match some input. It would be the<br class="">neutral element for the monoid operation that concatenates parsers.<br class=""><br class="">Olaf<br class=""><br class="">[1] <a href="https://en.wikibooks.org/wiki/Haskell/Alternative_and_MonadPlus" class="">https://en.wikibooks.org/wiki/Haskell/Alternative_and_MonadPlus</a><br class="">[2] <a href="https://wiki.haskell.org/MonadPlus" class="">https://wiki.haskell.org/MonadPlus</a><br class=""><br class=""><br class=""></blockquote>_______________________________________________<br class="">Haskell-Cafe mailing list<br class="">To (un)subscribe, modify options or view archives go to:<br class=""><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" class="">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br class="">Only members subscribed via the mailman list are allowed to post.<br class=""></blockquote>_______________________________________________<br class="">Haskell-Cafe mailing list<br class="">To (un)subscribe, modify options or view archives go to:<br class=""><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" class="">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br class="">Only members subscribed via the mailman list are allowed to post.<br class=""></blockquote><br class=""><br class=""></blockquote>_______________________________________________<br class="">Haskell-Cafe mailing list<br class="">To (un)subscribe, modify options or view archives go to:<br class=""><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" class="">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br class="">Only members subscribed via the mailman list are allowed to post.<br class=""></blockquote>_______________________________________________<br class="">Haskell-Cafe mailing list<br class="">To (un)subscribe, modify options or view archives go to:<br class=""><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" class="">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br class="">Only members subscribed via the mailman list are allowed to post.<br class=""></blockquote></blockquote>_______________________________________________<br class="">Haskell-Cafe mailing list<br class="">To (un)subscribe, modify options or view archives go to:<br class=""><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" class="">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe</a><br class="">Only members subscribed via the mailman list are allowed to post.</div></div></blockquote></div><br class=""></div></body></html>