mrkkrp / parser-combinators

Lightweight package providing commonly useful parser combinators
Other
52 stars 15 forks source link

[proposal] sepByN #31

Open epoberezkin opened 4 years ago

epoberezkin commented 4 years ago

Thanks for the library!

I was looking for something like sepBy but requiring an exact number of separated elements.

If it's not here yet, maybe it could be added:

sepByN :: Alternative m => m a -> m sep -> Int -> m [a]
sepByN x sep n = (:) <$> x <*> count (n-1) (sep *> x)

It can be used in this "semantic" way:

n & x `sepByN` sep
mrkkrp commented 4 years ago

I'm just wondering how common the idiom is. There is a balance between providing all possible combinators (we can sure define many) and keeping the library reasonably slim.

epoberezkin commented 4 years ago

I understand. Probably best to keep the issue open to see if there is any interest.

sullyj3 commented 1 year ago

I just wrote this exact function with the exact same name, and came here to propose adding it. Lo and behold, it was one of the 3 open feature requests 😄

sepByN :: Int -> Parser a -> Parser sep -> Parser [a]
sepByN n p sep = p <:> replicateM (n-1) (sep *> p)
  where (<:>) = liftA2 (:)

Use case was parsing 5*5 bingo boards for advent of code 2021 like this

1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
5 6 7 8 9