Thanks. So I tried<div><br></div><div><div><div>upTo n p =</div><div> liftM2 (:) p (upTo (n-1) p)</div><div><br></div><div>which doesn't quite work because the recursion does not have a base case. The following gets me closer:</div>
<div><br></div><div><div>upTo n p =</div><div> if n <= 0 then</div><div> return []</div><div> else</div><div> liftM2 (:) p (upTo (n-1) p)</div><div><br></div></div><div>> parse (upTo 3 digit) "" "123ab"</div>
<div>Right "123"</div><div><br></div><div>However:</div><div><br></div><div><div>> parse (upTo 4 digit) "" "123ab"</div><div>Left (line 1, column 4):</div><div>unexpected "a"</div>
<div>expecting digit</div><div><br></div></div><div>The semantics of (upTo n p) should be to parse at most n tokens, but if less than n tokens are available that should still be a successful parse. And the next token should be the first one upTo failed on.</div>
<div><br></div><div>I attempted to use the "try" parser in various locations but that doesn't seem to help, or maybe I'm using it incorrectly.</div><div><br></div></div><div><br></div></div><div><div class="gmail_quote">
On Sat, Oct 17, 2009 at 5:15 AM, Christian Maeder <span dir="ltr"><<a href="mailto:Christian.Maeder@dfki.de">Christian.Maeder@dfki.de</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Ashish Agarwal schrieb:<br>
<div><div></div><div class="h5">> Hi. I'm just learning Parsec and Haskell. It is a great library, and I<br>
> see how "many" lets you parse 0 or more items, "many1" parses 1 or more<br>
> items, and "count" parses exactly n items. However, there is no<br>
> combinator that parses between m and n items. What would be the best<br>
> implementation for this?<br>
<br>
</div></div>I would write an "upTo" parser with the same type as "count" that parses<br>
not exactly but at most n items. Your desired parser is than the<br>
concatenated results of "count m p" and "upTo (n - m) p" (achieved by<br>
"liftM2 (++)").<br>
<br>
For "upTo" a recursive definition seems best (other may come up with<br>
tricky combinator application.) "upTo 0 p" (or something less than 0)<br>
returns "[]" and "upTo n p" is an "option [] ..." parser of one "p"<br>
result followed by the "upTo (n - 1) p" result:<br>
<br>
"option [] (liftM2 (:) p (upTo (n - 1) p))"<br>
<br>
HTH Christian<br>
<br>
Another possibility is to use "many" and check if the resulting list has<br>
the desired length (if not fail), but that may consume too many tokens<br>
that subsequent parsers are supposed to consume.<br>
</blockquote></div><br></div>