Merge branch 'master' into bench
`bounded` and `upperBounded` combinators
This commit is contained in:
commit
be761a53f1
1 changed files with 43 additions and 0 deletions
|
@ -86,6 +86,8 @@ module Turtle.Pattern (
|
||||||
, selfless
|
, selfless
|
||||||
, choice
|
, choice
|
||||||
, count
|
, count
|
||||||
|
, upperBounded
|
||||||
|
, bounded
|
||||||
, option
|
, option
|
||||||
, between
|
, between
|
||||||
, skip
|
, skip
|
||||||
|
@ -524,6 +526,47 @@ choice = msum
|
||||||
count :: Int -> Pattern a -> Pattern [a]
|
count :: Int -> Pattern a -> Pattern [a]
|
||||||
count = replicateM
|
count = replicateM
|
||||||
|
|
||||||
|
{-| Apply the given pattern 0 or more times, up to a given bound,
|
||||||
|
colleting the results
|
||||||
|
|
||||||
|
>>> match (upperBounded 5 dot) "123"
|
||||||
|
["123"]
|
||||||
|
>>> match (upperBounded 2 dot) "123"
|
||||||
|
[]
|
||||||
|
>>> match ((,) <$> upperBounded 2 dot <*> chars) "123"
|
||||||
|
[("12","3"),("1","23")]
|
||||||
|
-}
|
||||||
|
|
||||||
|
upperBounded :: Int -> Pattern a -> Pattern [a]
|
||||||
|
upperBounded n p
|
||||||
|
| n <= 0 = mempty
|
||||||
|
| n == 1 = fmap pure p
|
||||||
|
| otherwise = (:) <$> p <*> option (upperBounded (n - 1) p)
|
||||||
|
|
||||||
|
{-| Apply the given pattern a number of times restricted by given
|
||||||
|
lower and upper bounds, collecting the results
|
||||||
|
|
||||||
|
>>> match (bounded 2 5 "cat") "catcatcat"
|
||||||
|
[["cat","cat","cat"]]
|
||||||
|
>>> match (bounded 2 5 "cat") "cat"
|
||||||
|
[]
|
||||||
|
>>> match (bounded 2 5 "cat") "catcatcatcatcatcat"
|
||||||
|
[]
|
||||||
|
|
||||||
|
`bounded` could be implemented naively as follows:
|
||||||
|
|
||||||
|
> bounded m n p = do
|
||||||
|
> x <- choice (map pure [m..n])
|
||||||
|
> count x p
|
||||||
|
|
||||||
|
-}
|
||||||
|
|
||||||
|
bounded :: Int -> Int -> Pattern a -> Pattern [a]
|
||||||
|
bounded m n p
|
||||||
|
| m == n = count m p
|
||||||
|
| m < n = (++) <$> count m p <*> option (upperBounded (n - m) p)
|
||||||
|
| otherwise = mzero
|
||||||
|
|
||||||
{-| Transform a parser to a succeed with an empty value instead of failing
|
{-| Transform a parser to a succeed with an empty value instead of failing
|
||||||
|
|
||||||
See also: `optional`
|
See also: `optional`
|
||||||
|
|
Loading…
Reference in a new issue