{-# LANGUAGE Trustworthy #-}
{-|
Module      : Text.Gigaparsec.Combinator
Description : This module contains a huge number of pre-made combinators that are
              very useful for a variety of purposes.
License     : BSD-3-Clause
Maintainer  : Jamie Willis, Gigaparsec Maintainers
Stability   : stable

This module contains a huge number of pre-made combinators that are very useful for a variety of purposes.

In particular, it contains combinators for: performing a parser iteratively, collecting all the results;
querying whether or not any input is left; optionally performing parsers; parsing delimited constructions;
handling multiple possible alternatives or parsers to sequence; handling more complex conditional execution;
and more.

@since 0.1.0.0
-}
module Text.Gigaparsec.Combinator (
  -- * Iterative Combinators
  -- | These combinators all execute a given parser an unbounded number of times, until either it fails, or another
  -- parser succeeds, depending on the combinator. Depending on the combinator, all of the results produced by the
  -- repeated execution of the parser may be returned in a @[]@. These are almost essential for any practical parsing
  -- task.
    manyN, skipMany, skipSome, skipManyN, count, count1, manyTill, someTill, skipManyTill, skipSomeTill,

  -- * Optional Parsing Combinators
  -- | These combinators allow for the /possible/ parsing of some parser. If the parser succeeds, that is ok
  -- so long as it __did not consume input__. Be aware that the result of the success may be replaced with
  -- these combinators, with the exception of "option", which still preserves the result.
    option, optional, optionalAs, decide, fromMaybeS,

  -- * Separated Values Combinators
  -- | These combinators are concerned with delimited parsing, where one parser is repeated but delimited by another one.
  -- In each of these cases @p@ is the parser of interest and @sep@ is the delimeter. These combinators mainly differ
  -- in either the number of @p@s they require, or exactly where the delimeters are allowed (only between, always
  -- trailing, or either). In all cases, they return the list of results generated by the repeated parses of @p@.
    sepBy, sepBy1, sepEndBy, sepEndBy1, endBy, endBy1,

  -- * Multiple Branching/Sequencing Combinators
  -- | These combinators allow for testing or sequencing a large number of parsers in one go.
    choice, sequence, traverse, skip,

  -- * Range Combinators
  -- | These combinators allow for the parsing of a specific parser either a specific number of times, or between a certain
  -- amount of times.
    exactly, range, range_, countRange,

  -- * Selective Combinators
  -- | These combinators allow for the conditional extraction of a result, or the execution of a parser
  -- based on another. They are derived from 'Text.Gigaparsec.branch'.
    ifS, whenS, guardS, whileS,
  ) where

import Text.Gigaparsec (Parsec, ($>), (<:>), unit, manyl, somel, notFollowedBy)
import Control.Applicative ((<|>), empty, liftA2, many, some)
import Control.Selective (select, branch)
import Data.Functor (void)
import Data.Foldable (asum, sequenceA_)

{-|
This combinator tries to parse each of the parsers @ps@ in order, until one of them succeeds.

Finds the first parser in @ps@ which succeeds, returning its result. If Nothing of the parsers
succeed, then this combinator fails. If a parser fails having consumed input, this combinator
fails __immediately__.

==== __Examples__
>>> let p = choice [string "abc", string "ab", string "bc", string "d"]
>>> parse @String p "abc"
Success "abc"
>>> parse @String p "ab"
Failure ..
>>> parse @String p "bc"
Success "bc"
>>> parse @String p "x"
Failure ..

@since 0.1.0.0
-}
choice :: [Parsec a] -- ^ the parsers, @ps@ to try, in order.
       -> Parsec a   -- ^ a parser that tries to parse one of @ps@.
choice :: forall a. [Parsec a] -> Parsec a
choice = [Parsec a] -> Parsec a
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum

{-|
This combinator will parse each of @ps@ in order, discarding the results.

Given the parsers @ps@, consisting of @p1@ through @pn@, parses
each in order. If they all succeed, this combinator succeeds. If any of
the parsers fail, then the whole combinator fails.

==== __Examples__
>>> let p = skip [char'a', item, char 'c']
>>> parse @String p "abc"
Success ()
>>> parse @String p "ab"
Failure ..

@since 0.1.0.0
-}
skip :: [Parsec a] -- ^ parsers @ps@ to be sequenced.
     -> Parsec ()  -- ^ a parser that parses each of @ps@, returning @()@.
skip :: forall a. [Parsec a] -> Parsec ()
skip = [Parsec a] -> Parsec ()
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Applicative f) =>
t (f a) -> f ()
sequenceA_

{-|
This combinator tries to parse @p@, wrapping its result in a @Just@ if it succeeds, or returns @Nothing@ if it fails.

Tries to parse @p@. If @p@ succeeded, producing @x@, then @Just x@ is returned. Otherwise, if @p@ failed
__without consuming input__, then @Nothing@ is returned instead.

==== __Examples__
>>> let p = option (string "abc")
>>> parse @String p ""
Success Nothing
>>> parse @String p "abc"
Success (Just "abc")
>>> parse @String p "ab"
Failure ..

@since 0.1.0.0
-}
option :: Parsec a         -- ^ the parser @p@ to try to parse
       -> Parsec (Maybe a)
option :: forall a. Parsec a -> Parsec (Maybe a)
option Parsec a
p = a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> Parsec a -> Parsec (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parsec a
p Parsec (Maybe a) -> Parsec (Maybe a) -> Parsec (Maybe a)
forall a. Parsec a -> Parsec a -> Parsec a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe a -> Parsec (Maybe a)
forall a. a -> Parsec a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing

{-|
This combinator will parse @p@ if possible, otherwise will do nothing.

Tries to parse @p@. If @p@ succeeds, or fails __without consuming input__ then this combinator is successful. Otherwise, if @p@ failed
having consumed input, this combinator fails.

==== __Examples__
>>> let p = optional (string "abc")
>>> parse @String p ""
Success ()
>>> parse @String p "abc"
Success ()
>>> parse @String p "ab"
Failure ..

@since 0.1.0.0
-}
optional :: Parsec a -- ^ the parser @p@ to try to parse.
         -> Parsec ()
optional :: forall a. Parsec a -> Parsec ()
optional = () -> Parsec a -> Parsec ()
forall b a. b -> Parsec a -> Parsec b
optionalAs ()

{-|
This combinator will parse @p@ if possible, otherwise will do nothing.

Tries to parse @p@. If @p@ succeeds, or fails __without consuming input__ then this combinator is successful and returns @x@. Otherwise,
if @p@ failed having consumed input, this combinator fails.

==== __Examples__
>>> let p = optionalAs 7 (string "abc")
>>> parse @String p ""
Success 7
>>> parse @String p "abc"
Success 7
>>> parse @String p "ab"
Failure ..

@since 0.1.0.0
-}
optionalAs :: b        -- ^ the value @x@ to return regardless of how @p@ performs.
           -> Parsec a -- ^ the parser @p@ to try to parse.
           -> Parsec b -- ^ a parser that tries to parse @p@, returning @x@ regardless of success or failure.
optionalAs :: forall b a. b -> Parsec a -> Parsec b
optionalAs b
x Parsec a
p = Parsec a
p Parsec a -> b -> Parsec b
forall a b. Parsec a -> b -> Parsec b
$> b
x Parsec b -> Parsec b -> Parsec b
forall a. Parsec a -> Parsec a -> Parsec a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> b -> Parsec b
forall a. a -> Parsec a
forall (f :: * -> *) a. Applicative f => a -> f a
pure b
x

-- TODO: collect
{-|
This combinator can eliminate a @Maybe@ from the result of the parser @p@.

First parse @p@, if it succeeds returning @Just x@, then return @x@. However,
if @p@ fails, or returned @Nothing@, then this combinator fails.

==== __Examples__
@decide (option p) = p@
-}
decide :: Parsec (Maybe a) -- ^ the parser @p@ to parse and extract the result from.
       -> Parsec a         -- ^ a parser that tries to extract the result from @p@.
decide :: forall a. Parsec (Maybe a) -> Parsec a
decide Parsec (Maybe a)
p = Parsec (Maybe a)
p Parsec (Maybe a) -> (Maybe a -> Parsec a) -> Parsec a
forall a b. Parsec a -> (a -> Parsec b) -> Parsec b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Parsec a -> (a -> Parsec a) -> Maybe a -> Parsec a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Parsec a
forall a. Parsec a
forall (f :: * -> *) a. Alternative f => f a
empty a -> Parsec a
forall a. a -> Parsec a
forall (f :: * -> *) a. Applicative f => a -> f a
pure

-- this is decide overload
{-|
This combinator parses @q@ depending only if @p@ returns a @Nothing@.

First parses @p@. If @p@ returned @Just x@, then @x@ is returned.
Otherwise, if @p@ returned @Nothing@ then @q@ is parsed, producing @y@,
and @y@ is returned. If @p@ or @q@ fails, the combinator fails.

==== __Examples__
fromMaybe q (option p) = p <|> q

@since 0.1.0.0
-}
fromMaybeS :: Parsec a         -- ^ a parser to execute when @p@ returns @Nothing@, to provide a value of type @a@.
           -> Parsec (Maybe a) -- ^ the first parser @p@, which returns an @Maybe@ to eliminate.
           -> Parsec a         -- ^ a parser that either just parses @p@ or both @p@ and @q@ in order to return an @a@.
fromMaybeS :: forall a. Parsec a -> Parsec (Maybe a) -> Parsec a
fromMaybeS Parsec a
q Parsec (Maybe a)
p = Parsec (Either () a) -> Parsec (() -> a) -> Parsec a
forall a b. Parsec (Either a b) -> Parsec (a -> b) -> Parsec b
forall (f :: * -> *) a b.
Selective f =>
f (Either a b) -> f (a -> b) -> f b
select (Either () a -> (a -> Either () a) -> Maybe a -> Either () a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> Either () a
forall a b. a -> Either a b
Left ()) a -> Either () a
forall a b. b -> Either a b
Right (Maybe a -> Either () a)
-> Parsec (Maybe a) -> Parsec (Either () a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parsec (Maybe a)
p) (a -> () -> a
forall a b. a -> b -> a
const (a -> () -> a) -> Parsec a -> Parsec (() -> a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parsec a
q)

{-|
This combinator repeatedly parses a given parser __@n@__ or more times, collecting the results into a list.

Parses a given parser, @p@, repeatedly until it fails. If @p@ failed having consumed input,
this combinator fails. Otherwise when @p@ fails __without consuming input__, this combinator
will return all of the results, @x1@ through @xm@ (with @m >= n@), in a list: @[x1, .., xm]@.
If @p@ was not successful at least @n@ times, this combinator fails.

==== __Examples__
>>> let p = manyN 2 (string "ab")
>>> parse @String p ""
Failure ..
>>> parse @String p "ab"
Failure ..
>>> parse @String p "abababab"
Success ["ab", "ab", "ab", "ab"]
>>> parse @String p "aba"
Failure ..

==== Notes
* @many p == many 0 p@ and @some p == many 1 p@.

@since 0.1.0.0
-}
manyN :: Int        -- ^ the minimum number of @p@s required, @n@.
      -> Parsec a   -- ^ the parser @p@ to execute multiple times.
      -> Parsec [a] -- ^ a parser that parses @p@ until it fails, returning the list of all the successful results.
manyN :: forall a. Int -> Parsec a -> Parsec [a]
manyN Int
0 Parsec a
p = Parsec a -> Parsec [a]
forall a. Parsec a -> Parsec [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many Parsec a
p
manyN Int
1 Parsec a
p = Parsec a -> Parsec [a]
forall a. Parsec a -> Parsec [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
some Parsec a
p
manyN Int
n Parsec a
p = Parsec a
p Parsec a -> Parsec [a] -> Parsec [a]
forall a. Parsec a -> Parsec [a] -> Parsec [a]
<:> Int -> Parsec a -> Parsec [a]
forall a. Int -> Parsec a -> Parsec [a]
manyN (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Parsec a
p

{-|
This combinator repeatedly parses a given parser __zero__ or more times, ignoring the results.

Parses a given parser, @p@, repeatedly until it fails. If @p@ failed having consumed input,
this combinator fails. Otherwise when @p@ fails __without consuming input__, this combinator
will succeed.

==== __Examples__
>>> let p = skipMany (string "ab")
>>> parse @String p ""
Success ()
>>> parse @String p "ab"
Success ()
>>> parse @String p "abababab"
Success ()
>>> parse @String p "aba"
Failure ..

@since 0.1.0.0
-}
skipMany :: Parsec a  -- ^ the parser @p@ to execute multiple times.
         -> Parsec () -- ^ a parser that parses @p@ until it fails, returning unit.
skipMany :: forall a. Parsec a -> Parsec ()
skipMany Parsec a
p = let go :: Parsec ()
go = Parsec a
p Parsec a -> Parsec () -> Parsec ()
forall a b. Parsec a -> Parsec b -> Parsec b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parsec ()
go Parsec () -> Parsec () -> Parsec ()
forall a. Parsec a -> Parsec a -> Parsec a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parsec ()
unit in Parsec ()
go

{-|
This combinator repeatedly parses a given parser __one__ or more times, ignoring the results.

Parses a given parser, @p@, repeatedly until it fails. If @p@ failed having consumed input,
this combinator fails. Otherwise when @p@ fails __without consuming input__, this combinator
will succeed. The parser @p@ must succeed at least once.

==== __Examples__
>>> let p = skipSome (string "ab")
>>> parse @String p ""
Failure ..
>>> parse @String p "ab"
Success ()
>>> parse @String p "abababab"
Success ()
>>> parse @String p "aba"
Failure ..

@since 0.1.0.0
-}
skipSome :: Parsec a  -- ^ @p@, the parser to execute multiple times.
         -> Parsec () -- ^ a parser that parses @p@ until it fails, returning unit.
skipSome :: forall a. Parsec a -> Parsec ()
skipSome Parsec a
p = Parsec a
p Parsec a -> Parsec () -> Parsec ()
forall a b. Parsec a -> Parsec b -> Parsec b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parsec a -> Parsec ()
forall a. Parsec a -> Parsec ()
skipMany Parsec a
p

{-|
This combinator repeatedly parses a given parser __@n@__ or more times, ignoring the results.

Parses a given parser, @p@, repeatedly until it fails. If @p@ failed having consumed input,
this combinator fails. Otherwise when @p@ fails __without consuming input__, this combinator
will succeed. The parser @p@ must succeed at least @n@ times.

==== __Examples__
>>> let p = skipManyN 2 (string "ab")
>>> parse @String p ""
Failure ..
>>> parse @String p "ab"
Failure ..
>>> parse @String p "abababab"
Success ()
>>> parse @String p "aba"
Failure ..

@since 0.1.0.0
-}
skipManyN :: Int       -- ^ @n@, the minimum number of times to execute.
          -> Parsec a  -- ^ @p@, the parser to execute multiple times.
          -> Parsec () -- ^ a parser that parses @p@ until it fails, returning unit.
skipManyN :: forall a. Int -> Parsec a -> Parsec ()
skipManyN Int
0 Parsec a
p = Parsec a -> Parsec ()
forall a. Parsec a -> Parsec ()
skipMany Parsec a
p
skipManyN Int
1 Parsec a
p = Parsec a -> Parsec ()
forall a. Parsec a -> Parsec ()
skipSome Parsec a
p
skipManyN Int
n Parsec a
p = Parsec a
p Parsec a -> Parsec () -> Parsec ()
forall a b. Parsec a -> Parsec b -> Parsec b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Int -> Parsec a -> Parsec ()
forall a. Int -> Parsec a -> Parsec ()
skipManyN (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Parsec a
p

{-|
This combinator repeatedly parses a given parser __zero__ or more times, returning how many times it succeeded.

Parses a given parser, @p@, repeatedly until it fails. If @p@ failed having consumed input,
this combinator fails. Otherwise when @p@ fails __without consuming input__, this combinator
will succeed. The number of times @p@ succeeded is returned as the result.

==== __Examples__
>>> let p = count (string "ab")
>>> parse @String p ""
Success 0
>>> parse @String p "ab"
Success 1
>>> parse @String p "abababab"
Success 4
>>> parse @String p "aba"
Failure ..

@since 0.1.0.0
-}
count :: Parsec a   -- ^ @p@, the parser to execute multiple times.
      -> Parsec Int -- ^ the number of times @p@ successfully parses
count :: forall a. Parsec a -> Parsec Int
count = (Int -> a -> Int) -> Int -> Parsec a -> Parsec Int
forall b a. (b -> a -> b) -> b -> Parsec a -> Parsec b
manyl ((a -> Int -> Int) -> Int -> a -> Int
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((Int -> Int) -> a -> Int -> Int
forall a b. a -> b -> a
const (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))) Int
0

{-|
This combinator repeatedly parses a given parser __one__ or more times, returning how many times it succeeded.

Parses a given parser, @p@, repeatedly until it fails. If @p@ failed having consumed input,
this combinator fails. Otherwise when @p@ fails __without consuming input__, this combinator
will succeed. The number of times @p@ succeeded is returned as the result.

The parser @p@ must succeed at least once.

==== __Examples__
>>> let p = count1 (string "ab")
>>> parse @String p ""
Failure ..
>>> parse @String p "ab"
Success 1
>>> parse @String p "abababab"
Success 4
>>> parse @String p "aba"
Failure ..

@since 0.1.0.0
-}
count1 :: Parsec a   -- ^ @p@, the parser to execute multiple times.
       -> Parsec Int -- ^ the number of times @p@ successfully parses
count1 :: forall a. Parsec a -> Parsec Int
count1 = (Int -> a -> Int) -> Int -> Parsec a -> Parsec Int
forall b a. (b -> a -> b) -> b -> Parsec a -> Parsec b
somel ((a -> Int -> Int) -> Int -> a -> Int
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((Int -> Int) -> a -> Int -> Int
forall a b. a -> b -> a
const (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))) Int
0

{-|
This combinator parses __zero__ or more occurrences of @p@, separated by @sep@.

Behaves just like 'sepBy1', except does not require an initial @p@, returning the empty list instead.

==== __Examples__
>>> ...
>>> let args = sepBy int (string ", ")
>>> parse @String args "7, 3, 2"
Success [7, 3, 2]
>>> parse @String args ""
Success []
>>> parse @String args "1"
Success [1]
>>> parse @String args "1, 2, "
Failure ..

@since 0.1.0.0
-}
sepBy :: Parsec a   -- ^ @p@, the parser whose results are collected into a list.
      -> Parsec sep -- ^ @sep@, the delimiter that must be parsed between every @p@.
      -> Parsec [a] -- ^ a parser that parses @p@ delimited by @sep@, returning the list of @p@'s results.
sepBy :: forall a sep. Parsec a -> Parsec sep -> Parsec [a]
sepBy Parsec a
p Parsec sep
sep = Parsec a -> Parsec sep -> Parsec [a]
forall a sep. Parsec a -> Parsec sep -> Parsec [a]
sepBy1 Parsec a
p Parsec sep
sep Parsec [a] -> Parsec [a] -> Parsec [a]
forall a. Parsec a -> Parsec a -> Parsec a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [a] -> Parsec [a]
forall a. a -> Parsec a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []

{-|
This combinator parses __one__ or more occurrences of @p@, separated by @sep@.

First parses a @p@. Then parses @sep@ followed by @p@ until there are no more @sep@s.
The results of the @p@'s, @x1@ through @xn@, are returned as @[x1, .., xn]@.
If @p@ or @sep@ fails having consumed input, the whole parser fails. 

Requires at least one @p@ to have been parsed.

==== __Examples__
>>> ...
>>> let args = sepBy1 int (string ", ")
>>> parse @String args "7, 3, 2"
Success [7, 3, 2]
>>> parse @String args ""
Failure ..
>>> parse @String args "1"
Success [1]
>>> parse @String args "1, 2, "
Failure ..

@since 0.1.0.0
-}
sepBy1 :: Parsec a   -- ^ @p@, the parser whose results are collected into a list.
       -> Parsec sep -- ^ @sep@, the delimiter that must be parsed between every @p@.
       -> Parsec [a] -- ^ a parser that parses @p@ delimited by @sep@, returning the list of @p@'s results.
sepBy1 :: forall a sep. Parsec a -> Parsec sep -> Parsec [a]
sepBy1 Parsec a
p Parsec sep
sep = Parsec a
p Parsec a -> Parsec [a] -> Parsec [a]
forall a. Parsec a -> Parsec [a] -> Parsec [a]
<:> Parsec a -> Parsec [a]
forall a. Parsec a -> Parsec [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
many (Parsec sep
sep Parsec sep -> Parsec a -> Parsec a
forall a b. Parsec a -> Parsec b -> Parsec b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parsec a
p)

{-|
This combinator parses __zero__ or more occurrences of @p@, separated and optionally ended by @sep@.

Behaves just like 'sepEndBy1', except does not require an initial @p@, returning the empty list instead.

==== __Examples__
>>> ...
>>> let args = sepEndBy int (string ";\n")
>>> parse @String args "7;\n3;\n2"
Success [7, 3, 2]
>>> parse @String args ""
Success Nil
>>> parse @String args "1"
Success [1]
>>> parse @String args "1;\n2;\n"
Success [1, 2]

@since 0.1.0.0
-}
sepEndBy :: Parsec a   -- ^ @p@, the parser whose results are collected into a list.
         -> Parsec sep -- ^ @sep@, the delimiter that must be parsed between every @p@.
         -> Parsec [a] -- ^ a parser that parses @p@ delimited by @sep@, returning the list of @p@'s results.
sepEndBy :: forall a sep. Parsec a -> Parsec sep -> Parsec [a]
sepEndBy Parsec a
p Parsec sep
sep = Parsec a -> Parsec sep -> Parsec [a]
forall a sep. Parsec a -> Parsec sep -> Parsec [a]
sepEndBy1 Parsec a
p Parsec sep
sep Parsec [a] -> Parsec [a] -> Parsec [a]
forall a. Parsec a -> Parsec a -> Parsec a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [a] -> Parsec [a]
forall a. a -> Parsec a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []

{-|
This combinator parses __one__ or more occurrences of @p@, separated and optionally ended by @sep@.

First parses a @p@. Then parses @sep@ followed by @p@ until there are no more: if a final @sep@ exists, this is parsed.
The results of the @p@'s, @x1@ through @xn@, are returned as @[x1, .., xn]@.
If @p@ or @sep@ fails having consumed input, the whole parser fails. 

Requires at least one @p@ to have been parsed.

==== __Examples__
>>> ...
>>> let args = sepEndBy1 int (string ";\n")
>>> parse @String args "7;\n3;\n2"
Success [7, 3, 2]
>>> parse @String args ""
Failure ..
>>> parse @String args "1"
Success [1]
>>> parse @String args "1;\n2;\n"
Success [1, 2]

@since 0.1.0.0
-}
sepEndBy1 :: Parsec a   -- ^ @p@, the parser whose results are collected into a list.
          -> Parsec sep -- ^ @sep@, the delimiter that must be parsed between every @p@.
          -> Parsec [a] -- ^ a parser that parses @p@ delimited by @sep@, returning the list of @p@'s results.
sepEndBy1 :: forall a sep. Parsec a -> Parsec sep -> Parsec [a]
sepEndBy1 Parsec a
p Parsec sep
sep = let seb1 :: Parsec [a]
seb1 = Parsec a
p Parsec a -> Parsec [a] -> Parsec [a]
forall a. Parsec a -> Parsec [a] -> Parsec [a]
<:> (Parsec sep
sep Parsec sep -> Parsec [a] -> Parsec [a]
forall a b. Parsec a -> Parsec b -> Parsec b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Parsec [a]
seb1 Parsec [a] -> Parsec [a] -> Parsec [a]
forall a. Parsec a -> Parsec a -> Parsec a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [a] -> Parsec [a]
forall a. a -> Parsec a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []) Parsec [a] -> Parsec [a] -> Parsec [a]
forall a. Parsec a -> Parsec a -> Parsec a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [a] -> Parsec [a]
forall a. a -> Parsec a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []) in Parsec [a]
seb1

{-|
This combinator parses __zero__ or more occurrences of @p@, separated and ended by @sep@.

Behaves just like 'endBy1', except does not require an initial @p@ and @sep@, returning the empty list instead.

==== __Examples__
>>> ...
>>> let args = endBy int (string ";\n")
>>> parse @String args "7;\n3;\n2"
Failure ..
>>> parse @String args ""
Success Nil
>>> parse @String args "1;\n"
Success [1]
>>> parse @String args "1;\n2;\n"
Success [1, 2]

@since 0.1.0.0
-}
endBy :: Parsec a   -- ^ @p@, the parser whose results are collected into a list.
      -> Parsec sep -- ^ @sep@, the delimiter that must be parsed between every @p@.
      -> Parsec [a] -- ^ a parser that parses @p@ delimited by @sep@, returning the list of @p@'s results.
endBy :: forall a sep. Parsec a -> Parsec sep -> Parsec [a]
endBy Parsec a
p Parsec sep
sep = Parsec a -> Parsec sep -> Parsec [a]
forall a sep. Parsec a -> Parsec sep -> Parsec [a]
endBy1 Parsec a
p Parsec sep
sep Parsec [a] -> Parsec [a] -> Parsec [a]
forall a. Parsec a -> Parsec a -> Parsec a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [a] -> Parsec [a]
forall a. a -> Parsec a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []

{-|
This combinator parses __one__ or more occurrences of @p@, separated and ended by @sep@.

Parses @p@ followed by @sep@ one or more times.
The results of the @p@'s, @x1@ through @xn@, are returned as @[x1, .., xn]@.
If @p@ or @sep@ fails having consumed input, the whole parser fails.

Requires at least one @p@ to have been parsed.

==== __Examples__
>>> ...
>>> let args = endBy1 int (string ";\n")
>>> parse @String args "7;\n3;\n2"
Failure ..
>>> parse @String args ""
Failure ..
>>> parse @String args "1;\n"
Success [1]
>>> parse @String args "1;\n2;\n"
Success [1, 2]

@since 0.1.0.0
-}
endBy1 :: Parsec a   -- ^ @p@, the parser whose results are collected into a list.
       -> Parsec sep -- ^ @sep@, the delimiter that must be parsed between every @p@.
       -> Parsec [a] -- ^ a parser that parses @p@ delimited by @sep@, returning the list of @p@'s results.
endBy1 :: forall a sep. Parsec a -> Parsec sep -> Parsec [a]
endBy1 Parsec a
p Parsec sep
sep = Parsec a -> Parsec [a]
forall a. Parsec a -> Parsec [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
some (Parsec a
p Parsec a -> Parsec sep -> Parsec a
forall a b. Parsec a -> Parsec b -> Parsec a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parsec sep
sep)

{-|
This combinator repeatedly parses a given parser __zero__ or more times, until the @end@ parser succeeds, collecting the results into a list.

First tries to parse @end@, if it fails __without consuming input__, then parses @p@, which must succeed. This repeats until @end@ succeeds.
When @end@ does succeed, this combinator will return all of the results generated by @p@, @x1@ through @xn@ (with @n >= 0@), in a
list: @[x1, .., xn]@. If @end@ could be parsed immediately, the empty list is returned.

==== __Examples__
This can be useful for scanning comments:

>>> let comment = string "--" *> manyUntil item endOfLine
>>> parse @String p "--hello world"
Failure ..
>>> parse @String p "--hello world\n"
Success ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
>>> parse @String p "--\n"
Success Nil

@since 0.1.0.0
-}
manyTill :: Parsec a   -- ^ @p@, the parser to execute multiple times.
         -> Parsec end -- ^ @end@, the parser that stops the parsing of @p@.
         -> Parsec [a] -- ^ a parser that parses @p@ until @end@ succeeds, returning the list of all the successful results.
manyTill :: forall a sep. Parsec a -> Parsec sep -> Parsec [a]
manyTill Parsec a
p Parsec end
end = let go :: Parsec [a]
go = Parsec end
end Parsec end -> [a] -> Parsec [a]
forall a b. Parsec a -> b -> Parsec b
$> [] Parsec [a] -> Parsec [a] -> Parsec [a]
forall a. Parsec a -> Parsec a -> Parsec a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parsec a
p Parsec a -> Parsec [a] -> Parsec [a]
forall a. Parsec a -> Parsec [a] -> Parsec [a]
<:> Parsec [a]
go in Parsec [a]
go

{-|
This combinator repeatedly parses a given parser __one__ or more times, until the @end@ parser succeeds, collecting the results into a list.

First ensures that trying to parse @end@ fails, then tries to parse @p@. If it succeeds then it will repeatedly: try to parse @end@, if it fails
__without consuming input__, then parses @p@, which must succeed. When @end@ does succeed, this combinator will return all of the results
generated by @p@, @x1@ through @xn@ (with @n >= 1@), in a list: @[x1, .., xn]@. 

The parser @p@ must succeed at least once before @end@ succeeds.

==== __Examples__
This can be useful for scanning comments:

>>> let comment = string "--" *> someUntil item endOfLine
>>> parse @String p "--hello world"
Failure ..
>>> parse @String p "--hello world\n"
Success ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
>>> parse @String p "--\n"
Failure ..
>>> parse @String p "--a\n"
Success ['a']

@since 0.1.0.0
-}
someTill :: Parsec a   -- ^ @p@, the parser to execute multiple times, at least once.
         -> Parsec end -- ^ @end@, the parser that stops the parsing of @p@.
         -> Parsec [a] -- ^ a parser that parses @p@ until @end@ succeeds, returning the list of all the successful results.
someTill :: forall a sep. Parsec a -> Parsec sep -> Parsec [a]
someTill Parsec a
p Parsec end
end = Parsec end -> Parsec ()
forall a. Parsec a -> Parsec ()
notFollowedBy Parsec end
end Parsec () -> Parsec [a] -> Parsec [a]
forall a b. Parsec a -> Parsec b -> Parsec b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Parsec a
p Parsec a -> Parsec [a] -> Parsec [a]
forall a. Parsec a -> Parsec [a] -> Parsec [a]
<:> Parsec a -> Parsec end -> Parsec [a]
forall a sep. Parsec a -> Parsec sep -> Parsec [a]
manyTill Parsec a
p Parsec end
end)

{-|
This combinator repeatedly parses a given parser __zero__ or more times, until the @end@ parser succeeds, discarding any results from @p@.

Behaves like 'manyTill', except the results of parsing @p@ are ignored.

First tries to parse @end@, if it fails __without consuming input__, then parses @p@, which must succeed. This repeats until @end@ succeeds.
When @end@ does succeed (even of the first try), this combinator will discard any results generated by @p@. 

-}
skipManyTill  :: Parsec a   -- ^ @p@, the parser to execute multiple times
              -> Parsec end -- ^ @end@, the parser that stops the parsing of @p@
              -> Parsec ()  -- ^ a parser that parses @p@ until @end@ succeeds, returning unit.
skipManyTill :: forall a end. Parsec a -> Parsec end -> Parsec ()
skipManyTill Parsec a
p Parsec end
end = Parsec [a] -> Parsec ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Parsec a -> Parsec end -> Parsec [a]
forall a sep. Parsec a -> Parsec sep -> Parsec [a]
manyTill Parsec a
p Parsec end
end)

{-|
This combinator repeatedly parses a given parser __one__ or more times, until the @end@ parser succeeds, discarding any results from @p@, and returns unit.

Behaves like 'someTill', except the results of parsing @p@ are ignored.

First ensures that trying to parse @end@ fails, then tries to parse @p@. If it succeeds then it will repeatedly: try to parse @end@, if it fails
__without consuming input__, then parses @p@, which must succeed. 
When @end@ does succeed, this combinator will discard any results generated by @p@, returning unit. 

The parser @p@ must succeed at least once before @end@ succeeds.
-}
skipSomeTill  :: Parsec a   -- ^ @p@, the parser to execute multiple times, at least once.
              -> Parsec end -- ^ @end@, the parser that stops the parsing of @p@.
              -> Parsec ()  -- ^ a parser that parses @p@ until @end@ succeeds, returning unit.
skipSomeTill :: forall a end. Parsec a -> Parsec end -> Parsec ()
skipSomeTill Parsec a
p Parsec end
end = Parsec [a] -> Parsec ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Parsec a -> Parsec end -> Parsec [a]
forall a sep. Parsec a -> Parsec sep -> Parsec [a]
someTill Parsec a
p Parsec end
end)

-- this is ifP
{-|
This combinator parses one of @thenP@ or @elseP@ depending on the result of parsing @condP@.

This is a lifted @if@-statement. First, parse @condP@: if it is successful and returns
@True@, then parse @thenP@; else, if it returned @False@, parse @elseP@; or, if @condP@ failed
then fail. If either of @thenP@ or @elseP@ fail, then this combinator also fails.

Most useful in conjunction with /Registers/, as this allows for decisions to be made
based on state.

==== __Examples__
>>> ifP (pure True) p _ == p
>>> ifP (pure False) _ p == p

@since 0.1.0.0
-}
ifS :: Parsec Bool -- ^ @condP@, the parser that yields the condition value.
    -> Parsec a    -- ^ @thenP@, the parser to execute if the condition is @True@.
    -> Parsec a    -- ^ @elseP@, the parser to execute if the condition is @False@.
    -> Parsec a    -- ^ a parser that conditionally parses @thenP@ or @elseP@ after @condP@.
ifS :: forall a. Parsec Bool -> Parsec a -> Parsec a -> Parsec a
ifS Parsec Bool
cond Parsec a
t Parsec a
e = Parsec (Either () ())
-> Parsec (() -> a) -> Parsec (() -> a) -> Parsec a
forall (f :: * -> *) a b c.
Selective f =>
f (Either a b) -> f (a -> c) -> f (b -> c) -> f c
branch (Bool -> Either () ()
bool (Bool -> Either () ()) -> Parsec Bool -> Parsec (Either () ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parsec Bool
cond) (a -> () -> a
forall a b. a -> b -> a
const (a -> () -> a) -> Parsec a -> Parsec (() -> a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parsec a
e) (a -> () -> a
forall a b. a -> b -> a
const (a -> () -> a) -> Parsec a -> Parsec (() -> a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parsec a
t)
  where bool :: Bool -> Either () ()
bool Bool
True = () -> Either () ()
forall a b. b -> Either a b
Right ()
        bool Bool
False = () -> Either () ()
forall a b. a -> Either a b
Left ()

-- this is when
{-|
This combinator conditionally parses @thenP@ depending on the result of parsing @condP@.

This is a lifted @if@-statement. First, parse @condP@: if it is successful and returns
@True@, then parse @thenP@; else, if it returned @False@ do nothing; or, if @condP@ failed
then fail. If @thenP@ fails, then this combinator also fails.

Most useful in conjunction with /Registers/, as this allows for decisions to be made
based on state.

==== __Examples__
>>> when (pure True) p == p
>>> when (pure False) _ == unit

@since 0.1.0.0
-}
whenS :: Parsec Bool -- ^ @condP@, the parser that yields the condition value.
      -> Parsec ()   -- ^ @thenP@, the parser to execute if the condition is @True@.
      -> Parsec ()   -- ^ a parser that conditionally parses @thenP@ after @condP@.
whenS :: Parsec Bool -> Parsec () -> Parsec ()
whenS Parsec Bool
cond Parsec ()
p = Parsec Bool -> Parsec () -> Parsec () -> Parsec ()
forall a. Parsec Bool -> Parsec a -> Parsec a -> Parsec a
ifS Parsec Bool
cond Parsec ()
p Parsec ()
unit

-- this is guard
{-|
This combinator verfies that the given parser returns @True@, or else fails.

First, parse @p@; if it succeeds then, so long at returns @True@, this @guard p@ succeeds. Otherwise,
if @p@ either fails, or returns @False@, @guard p@ will fail.

==== __Examples__
>>> guard (pure True) == unit
>>> guard (pure False) == empty
>>> when (not <$> p) empty == guard p

@since 0.1.0.0
-}
guardS :: Parsec Bool -- ^ @p@, the parser that yields the condition value.
       -> Parsec ()
guardS :: Parsec Bool -> Parsec ()
guardS Parsec Bool
cond = Parsec Bool -> Parsec () -> Parsec () -> Parsec ()
forall a. Parsec Bool -> Parsec a -> Parsec a -> Parsec a
ifS Parsec Bool
cond Parsec ()
unit Parsec ()
forall a. Parsec a
forall (f :: * -> *) a. Alternative f => f a
empty

-- this is whileP
{-|
This combinator repeatedly parses @p@ so long as it returns @True@.

This is a lifted @while@-loop. First, parse @p@: if it is successful and
returns @True@, then repeat; else if it returned @False@ stop; or, if it
failed then this combinator fails.

Most useful in conjunction with /Registers/, as this allows for decisions to be made
based on state. In particular, this can be used to define the @forP@ combinator.

@since 0.1.0.0
-}
whileS :: Parsec Bool -- ^ @p@, the parser to repeatedly parse.
       -> Parsec ()   -- ^ a parser that continues to parse @p@ until it returns @False@.
whileS :: Parsec Bool -> Parsec ()
whileS Parsec Bool
c = let go :: Parsec ()
go = Parsec Bool -> Parsec () -> Parsec ()
whenS Parsec Bool
c Parsec ()
go in Parsec ()
go

{-|
This combinator parses exactly @n@ occurrences of @p@, returning these @n@ results in a list.

Parses @p@ repeatedly up to @n@ times. If @p@ fails before @n@ is reached, then this combinator
fails. It is not required for @p@ to fail after the @n@th parse. The results produced by
@p@, @x1@ through @xn@, are returned as @[x1, .., xn]@.

==== __Examples__
>>> let p = exactly 3 item
>>> parse @String p "ab"
Failure ..
>>> parse @String p "abc"
Success ['a', 'b', 'c']
>>> parse @String p "abcd"
Success ['a', 'b', 'c']

@since 0.1.0.0
-}
exactly :: Int        -- ^ @n@, the number of times to repeat @p@.
        -> Parsec a   -- ^ @p@, the parser to repeat.
        -> Parsec [a] -- ^ a parser that parses @p@ exactly @n@ times, returning a list of the results.
exactly :: forall a. Int -> Parsec a -> Parsec [a]
exactly Int
n = Int -> Int -> Parsec a -> Parsec [a]
forall a. Int -> Int -> Parsec a -> Parsec [a]
range Int
n Int
n

{-|
This combinator parses between @min@ and @max@ occurrences of @p@, returning these @n@ results in a list.

Parses @p@ repeatedly a minimum of @min@ times and up to @max@ times both inclusive. If @p@ fails before
@min@ is reached, then this combinator fails. It is not required for @p@ to fail after the @max@^th^ parse.
The results produced by @p@, @xmin@ through @xmax@, are returned as @[xmin, .., xmax]@.

==== __Examples__
>>> let p = range 3 5 item
>>> parse @String p "ab"
Failure ..
>>> parse @String p "abc"
Success ['a', 'b', 'c']
>>> parse @String p "abcd"
Success ['a', 'b', 'c', 'd']
>>> parse @String p "abcde"
Success ['a', 'b', 'c', 'd', 'e']
>>> parse @String p "abcdef"
Success ['a', 'b', 'c', 'd', 'e']

@since 0.1.0.0
-}
range :: Int        -- ^ @min@, the minimum number of times to repeat @p@, inclusive.
      -> Int        -- ^ @max@, the maximum number of times to repeat @p@, inclusive.
      -> Parsec a   -- ^ @p@, the parser to repeat.
      -> Parsec [a] -- ^ the results of the successful parses of @p@.
range :: forall a. Int -> Int -> Parsec a -> Parsec [a]
range Int
mn Int
mx Parsec a
p
  | Int
mn Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
mx Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
mn = [a] -> Parsec [a]
forall a. a -> Parsec a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
  | Bool
otherwise = Int -> Int -> Parsec [a]
forall {t} {t}. (Eq t, Eq t, Num t, Num t) => t -> t -> Parsec [a]
go Int
mn Int
mx
  where
    go :: t -> t -> Parsec [a]
go t
0 t
0 = [a] -> Parsec [a]
forall a. a -> Parsec a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
    go t
0 t
n = Parsec a
p Parsec a -> Parsec [a] -> Parsec [a]
forall a. Parsec a -> Parsec [a] -> Parsec [a]
<:> t -> t -> Parsec [a]
go t
0 (t
n t -> t -> t
forall a. Num a => a -> a -> a
- t
1) Parsec [a] -> Parsec [a] -> Parsec [a]
forall a. Parsec a -> Parsec a -> Parsec a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> [a] -> Parsec [a]
forall a. a -> Parsec a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
    go t
m t
n = Parsec a
p Parsec a -> Parsec [a] -> Parsec [a]
forall a. Parsec a -> Parsec [a] -> Parsec [a]
<:> t -> t -> Parsec [a]
go (t
m t -> t -> t
forall a. Num a => a -> a -> a
- t
1) (t
n t -> t -> t
forall a. Num a => a -> a -> a
- t
1)

{-|
This combinator parses between @min@ and @max@ occurrences of @p@ but ignoring the results.

Parses @p@ repeatedly a minimum of @min@ times and up to @max@ times both inclusive. If @p@ fails before
@min@ is reached, then this combinator fails. It is not required for @p@ to fail after the @max@th parse.
The results are discarded and @()@ is returned instead.

==== __Examples__
>>> let p = range_ 3 5 item
>>> parse @String p "ab"
Failure ..
>>> parse @String p "abc"
Success ()
>>> parse @String p "abcd"
Success ()
>>> parse @String p "abcde"
Success ()
>>> parse @String p "abcdef"
Success ()

@since 0.1.0.0
-}
range_ :: Int       -- ^ @min@, the minimum number of times to repeat @p@, inclusive.
       -> Int       -- ^ @max@, the maximum number of times to repeat @p@, inclusive.
       -> Parsec a  -- ^ @p@, the parser to repeat.
       -> Parsec ()
range_ :: forall a. Int -> Int -> Parsec a -> Parsec ()
range_ Int
mn Int
mx Parsec a
p
  | Int
mn Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
mx Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
mn = Parsec ()
unit
  | Bool
otherwise = Int -> Int -> Parsec ()
forall {t} {t}. (Eq t, Eq t, Num t, Num t) => t -> t -> Parsec ()
go Int
mn Int
mx
  where
    go :: t -> t -> Parsec ()
go t
0 t
0 = Parsec ()
unit
    go t
0 t
n = Parsec () -> Parsec ()
forall a. Parsec a -> Parsec ()
optional (Parsec a
p Parsec a -> Parsec () -> Parsec ()
forall a b. Parsec a -> Parsec b -> Parsec b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> t -> t -> Parsec ()
go t
0 (t
n t -> t -> t
forall a. Num a => a -> a -> a
- t
1))
    go t
m t
n = Parsec a
p Parsec a -> Parsec () -> Parsec ()
forall a b. Parsec a -> Parsec b -> Parsec b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> t -> t -> Parsec ()
go (t
m t -> t -> t
forall a. Num a => a -> a -> a
- t
1) (t
n t -> t -> t
forall a. Num a => a -> a -> a
- t
1)

-- this is count overloading
{-|
This combinator parses between @min@ and @max@ occurrences of @p@, returning the number of successes.

Parses @p@ repeatedly a minimum of @min@ times and up to @max@ times both inclusive. If @p@ fails before
@min@ is reached, then this combinator fails. It is not required for @p@ to fail after the @max@th parse.
The results are discarded and the number of successful parses of @p@, @n@, is returned instead, such that
@min <= n <= max@.

==== __Examples__
>>> let p = count 3 5 item
>>> parse @String p "ab"
Failure ..
>>> parse @String p "abc"
Success 3
>>> parse @String p "abcd"
Success 4
>>> parse @String p "abcde"
Success 5
>>> parse @String p "abcdef"
Success 5

@since 0.1.0.0
-}
countRange :: Int        -- ^ @min@, the minimum number of times to repeat @p@, inclusive.
           -> Int        -- ^ @max@, the maximum number of times to repeat @p@, inclusive.
           -> Parsec a   -- ^ @p@, the parser to repeat.
           -> Parsec Int -- ^ the number of times @p@ parsed successfully.
countRange :: forall a. Int -> Int -> Parsec a -> Parsec Int
countRange Int
mn Int
mx Parsec a
p
  | Int
mn Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
mx Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
mn = Int -> Parsec Int
forall a. a -> Parsec a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
0
  | Bool
otherwise = Int -> Int -> Parsec Int
forall {t} {t} {a}.
(Eq t, Eq t, Num t, Num t, Num a) =>
t -> t -> Parsec a
go Int
mn Int
mx
  where
    go :: t -> t -> Parsec a
go t
0 t
0 = a -> Parsec a
forall a. a -> Parsec a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
0
    go t
0 t
n = (a -> a -> a) -> Parsec a -> Parsec a -> Parsec a
forall a b c. (a -> b -> c) -> Parsec a -> Parsec b -> Parsec c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 ((a -> a) -> a -> a -> a
forall a b. a -> b -> a
const (a -> a -> a
forall a. Num a => a -> a -> a
+ a
1)) Parsec a
p (t -> t -> Parsec a
go t
0 (t
n t -> t -> t
forall a. Num a => a -> a -> a
- t
1)) Parsec a -> Parsec a -> Parsec a
forall a. Parsec a -> Parsec a -> Parsec a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> a -> Parsec a
forall a. a -> Parsec a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
0
    go t
m t
n = (a -> a -> a) -> Parsec a -> Parsec a -> Parsec a
forall a b c. (a -> b -> c) -> Parsec a -> Parsec b -> Parsec c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 ((a -> a) -> a -> a -> a
forall a b. a -> b -> a
const (a -> a -> a
forall a. Num a => a -> a -> a
+ a
1)) Parsec a
p (t -> t -> Parsec a
go (t
m t -> t -> t
forall a. Num a => a -> a -> a
- t
1) (t
n t -> t -> t
forall a. Num a => a -> a -> a
- t
1))