<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="">Isn't  'u <*> empty = empty' resembles MonadPlus?<br class=""><div class=""><br class=""></div><div class=""><pre style="margin-top: 1em; margin-bottom: 0px; padding: 0.5rem 1rem; background-color: rgb(29, 31, 32); overflow: auto; border: 1px solid rgb(58, 62, 65); border-top-left-radius: 0.3em; border-top-right-radius: 0.3em; border-bottom-right-radius: 0.3em; border-bottom-left-radius: 0.3em; color: rgb(221, 218, 214); font-size: 14px; font-variant-ligatures: normal; letter-spacing: 0.024px; orphans: 2; widows: 2;" class="">mzero >>= f  =  mzero
v >> mzero   =  mzero</pre><div class=""><br class=""></div><div class="">Since ParsecT also has a MonadPlus instance, can we have different implementations of `empty` and `mzero` to have these 2 separate semantics expressible:</div><div class=""><br class=""></div><div class="">*) parse to ignored result from some input</div><div class="">*) un-parsable (input consumed or not is irrelevant as to err out anyway)</div><div class=""><br class=""></div><div class=""><table cellspacing="0" cellpadding="0" style="border-collapse: collapse" class="">
<tbody class="">
<tr class="">
<td valign="top" style="width: 56.0px; height: 35.0px; background-color: #b0b3b2; border-style: solid; border-width: 1.0px 1.0px 1.0px 1.0px; border-color: #000000 #000000 #000000 #000000; padding: 4.0px 4.0px 4.0px 4.0px" class=""><div style="margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; min-height: 14px;" class=""><br class=""></div>
</td>
<td valign="top" style="width: 60.0px; height: 35.0px; background-color: #b0b3b2; border-style: solid; border-width: 1.0px 1.0px 1.0px 1.0px; border-color: #000000 #000000 #000000 #000000; padding: 4.0px 4.0px 4.0px 4.0px" class=""><div style="margin: 0px;" class=""><font face="Helvetica Neue" color="#000000" style="font-stretch: normal; font-size: 10px; line-height: normal; font-family: "Helvetica Neue"; font-variant-ligatures: common-ligatures; color: rgb(0, 0, 0);" class=""><b class="">parse to no significant result</b></font></div>
</td>
<td valign="top" style="width: 53.0px; height: 35.0px; background-color: #b0b3b2; border-style: solid; border-width: 1.0px 1.0px 1.0px 1.0px; border-color: #000000 #000000 #000000 #000000; padding: 4.0px 4.0px 4.0px 4.0px" class=""><div style="margin: 0px;" class=""><font face="Helvetica Neue" color="#000000" style="font-stretch: normal; font-size: 10px; line-height: normal; font-family: "Helvetica Neue"; font-variant-ligatures: common-ligatures; color: rgb(0, 0, 0);" class=""><b class="">unparsable</b></font></div>
</td>
</tr>
<tr class="">
<td valign="top" style="width: 56.0px; height: 24.0px; background-color: #d4d4d4; border-style: solid; border-width: 1.0px 1.0px 1.0px 1.0px; border-color: #000000 #000000 #000000 #000000; padding: 4.0px 4.0px 4.0px 4.0px" class=""><div style="margin: 0px;" class=""><font face="Helvetica Neue" color="#000000" style="font-stretch: normal; font-size: 10px; line-height: normal; font-family: "Helvetica Neue"; font-variant-ligatures: common-ligatures; color: rgb(0, 0, 0);" class=""><b class="">consumed input</b></font></div>
</td>
<td valign="top" style="width: 60.0px; height: 24.0px; border-style: solid; border-width: 1.0px 1.0px 1.0px 1.0px; border-color: #000000 #000000 #000000 #000000; padding: 4.0px 4.0px 4.0px 4.0px" class=""><div style="margin: 0px;" class=""><font face="Helvetica Neue" color="#000000" style="font-stretch: normal; font-size: 10px; line-height: normal; font-family: "Helvetica Neue"; font-variant-ligatures: common-ligatures; color: rgb(0, 0, 0);" class="">empty -> throw ??</font></div>
</td>
<td valign="top" style="width: 53.0px; height: 24.0px; border-style: solid; border-width: 1.0px 1.0px 1.0px 1.0px; border-color: #000000 #000000 #000000 #000000; padding: 4.0px 4.0px 4.0px 4.0px" class=""><div style="margin: 0px;" class=""><font face="Helvetica Neue" color="#000000" style="font-stretch: normal; font-size: 10px; line-height: normal; font-family: "Helvetica Neue"; font-variant-ligatures: common-ligatures; color: rgb(0, 0, 0);" class="">mzero -> throw</font></div>
</td>
</tr>
<tr class="">
<td valign="top" style="width: 56.0px; height: 23.0px; background-color: #d4d4d4; border-style: solid; border-width: 1.0px 1.0px 1.0px 1.0px; border-color: #000000 #000000 #000000 #000000; padding: 4.0px 4.0px 4.0px 4.0px" class=""><div style="margin: 0px;" class=""><font face="Helvetica Neue" color="#000000" style="font-stretch: normal; font-size: 10px; line-height: normal; font-family: "Helvetica Neue"; font-variant-ligatures: common-ligatures; color: rgb(0, 0, 0);" class=""><b class="">no input consumed</b></font></div>
</td>
<td valign="top" style="width: 60.0px; height: 23.0px; border-style: solid; border-width: 1.0px 1.0px 1.0px 1.0px; border-color: #000000 #000000 #000000 #000000; padding: 4.0px 4.0px 4.0px 4.0px" class=""><div style="margin: 0px;" class=""><font face="Helvetica Neue" color="#000000" style="font-stretch: normal; font-size: 10px; line-height: normal; font-family: "Helvetica Neue"; font-variant-ligatures: common-ligatures; color: rgb(0, 0, 0);" class="">empty -> nothrow</font></div>
</td>
<td valign="top" style="width: 53.0px; height: 23.0px; border-style: solid; border-width: 1.0px 1.0px 1.0px 1.0px; border-color: #000000 #000000 #000000 #000000; padding: 4.0px 4.0px 4.0px 4.0px" class=""><div style="margin: 0px;" class=""><font face="Helvetica Neue" color="#000000" style="font-stretch: normal; font-size: 10px; line-height: normal; font-family: "Helvetica Neue"; font-variant-ligatures: common-ligatures; color: rgb(0, 0, 0);" class="">mzero -> throw</font></div>
</td>
</tr>
</tbody>
</table></div><div class=""><br class=""></div><div class="">I'd much like the behavior above `<span style="color: rgb(0, 0, 0); font-family: "Helvetica Neue"; font-size: 10px;" class="">empty -> throw ??</span>` changed to `<span style="color: rgb(0, 0, 0); font-family: "Helvetica Neue"; font-size: 10px;" class="">empty -> nothrow</span>` </div><div><br class=""><blockquote type="cite" class=""><div class="">On 2020-10-27, at 17:47, Jaro Reinders <<a href="mailto:jaro.reinders@gmail.com" class="">jaro.reinders@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div 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.</div></div></blockquote></div><br class=""></div></body></html>