# [Haskell-beginners] Re: parsing upto n items with parsec

Ashish Agarwal agarwal1975 at gmail.com
Mon Oct 19 12:22:48 EDT 2009

```Thanks. So I tried
upTo n p =
liftM2 (:) p (upTo (n-1) p)

which doesn't quite work because the recursion does not have a base case.
The following gets me closer:

upTo n p =
if n <= 0 then
return []
else
liftM2 (:) p (upTo (n-1) p)

> parse (upTo 3 digit) "" "123ab"
Right "123"

However:

> parse (upTo 4 digit) "" "123ab"
Left (line 1, column 4):
unexpected "a"
expecting digit

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.

I attempted to use the "try" parser in various locations but that doesn't
seem to help, or maybe I'm using it incorrectly.

On Sat, Oct 17, 2009 at 5:15 AM, Christian Maeder
<Christian.Maeder at dfki.de>wrote:

> Ashish Agarwal schrieb:
> > Hi. I'm just learning Parsec and Haskell. It is a great library, and I
> > see how "many" lets you parse 0 or more items, "many1" parses 1 or more
> > items, and "count" parses exactly n items. However, there is no
> > combinator that parses between m and n items. What would be the best
> > implementation for this?
>
> I would write an "upTo" parser with the same type as "count" that parses
> not exactly but at most n items. Your desired parser is than the
> concatenated results of "count m p" and "upTo (n - m) p" (achieved by
> "liftM2 (++)").
>
> For "upTo" a recursive definition seems best (other may come up with
> tricky combinator application.) "upTo 0 p" (or something less than 0)
> returns "[]" and "upTo n p" is an "option [] ..." parser of one "p"
> result followed by the "upTo (n - 1) p" result:
>
> "option [] (liftM2 (:) p (upTo (n - 1) p))"
>
> HTH Christian
>
> Another possibility is to use "many" and check if the resulting list has
> the desired length (if not fail), but that may consume too many tokens
> that subsequent parsers are supposed to consume.
>
-------------- next part --------------
An HTML attachment was scrubbed...