<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Jun 11, 2021 at 8:24 PM Askar Safin <<a href="mailto:safinaskar@mail.ru">safinaskar@mail.ru</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">So, we need this function instead:<br>
<br>
fromEither :: Parser (Either String a) -> Parser a </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Now we can write this:<br>
-----<br>
q :: Parser Int<br>
q = fromEither $ do { -- applicative do<br>
char '(';<br>
a <- p;<br>
char '/';<br>
b <- p;<br>
char ')';<br>
pure $ do { -- normal monadic do<br>
when (b == 0) $ Left "division by zero";<br>
return $ a / b;<br>
};<br>
}<br>
------<br>
Yay! Now everything works with Applicative. Moreover, it seems we can embed arbitrary Monad this way. But this is ugly. Because:<br>
1. We use two-level do. One applicative and one monadic<br>
2. We need to prepend "fromEither" before each parser, in which we plan to fail with error messages.<br></blockquote><div><br></div><div>Indeed. You can see this as a clear expression of the two-phase nature of the problem at hand. You want monadic effects (such as Either String) to be executed for type checking, but not during parsing, so that you can check for an ambiguous parse prior to performing type checking. Then you must have a separation between non-determinism in parsing (the Parser functor) and type checking failures (the nested Either monad). This appears in your types and code, by saying that a type checking failure counts as a successful parse, whose associated value is an error from the type checker.</div><div><br></div><div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">So, I think arrow parsing will be more natural<br></blockquote><div><br></div><div>That's an interesting hypothesis. I'm not familiar with any arrow-based parsing libraries, so if you try and find a better way to express this there, I hope you'll share your findings with us.</div><div><br></div><div>Chris</div></div></div>