{-# LANGUAGE PatternSynonyms #-}
{-|
Module      : Parsley.Fold
Description : The "folding" combinators: chains and iterators
License     : BSD-3-Clause
Maintainer  : Jamie Willis
Stability   : stable

This module contains the combinator concerned with some form of iteration or input folding. Notably,
this includes the traditional `many` and `some` combinators.

@since 0.1.0.0
-}
module Parsley.Fold (
    many, some, manyN,
    skipMany, skipSome, skipManyN,
    sepBy, sepBy1, endBy, endBy1, sepEndBy, sepEndBy1,
    chainl1, chainr1, chainl, chainr,
    chainl1', chainr1', chainPre, chainPost,
    pfoldr, pfoldl,
    pfoldr1, pfoldl1
  ) where

import Prelude hiding      (pure, (<*>), (<$>), (*>), (<*))
import Parsley.Alternative ((<|>), option)
import Parsley.Applicative (pure, (<*>), (<$>), (*>), (<*), (<:>), (<**>), void)
import Parsley.Internal    (Parser, Defunc(FLIP, ID, COMPOSE, EMPTY, CONS, CONST), ParserOps, pattern FLIP_H, pattern COMPOSE_H, pattern UNIT, chainPre, chainPost)
import Parsley.Register    (bind, get, modify, newRegister_)

{-chainPre :: Parser (a -> a) -> Parser a -> Parser a
chainPre op p = newRegister_ ID $ \acc ->
  let go = modify acc (FLIP_H COMPOSE <$> op) *> go
       <|> get acc
  in go <*> p-}

{-chainPost :: Parser a -> Parser (a -> a) -> Parser a
chainPost p op = newRegister p $ \acc ->
  let go = modify acc op *> go
       <|> get acc
  in go-}

-- Parser Folds
{-|
@pfoldr f k p@ parses __zero__ or more @p@s and combines the results using the function @f@. When @p@
fails without consuming input, the terminal result @k@ is returned.

> many = pfoldr CONS EMPTY

@since 0.1.0.0
-}
pfoldr :: (ParserOps repf, ParserOps repk) => repf (a -> b -> b) -> repk b -> Parser a -> Parser b
pfoldr :: repf (a -> b -> b) -> repk b -> Parser a -> Parser b
pfoldr repf (a -> b -> b)
f repk b
k Parser a
p = Parser (b -> b) -> Parser b -> Parser b
forall a. Parser (a -> a) -> Parser a -> Parser a
chainPre (repf (a -> b -> b)
f repf (a -> b -> b) -> Parser a -> Parser (b -> b)
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> Parser a
p) (repk b -> Parser b
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure repk b
k)

{-|
@pfoldr1 f k p@ parses __one__ or more @p@s and combines the results using the function @f@. When @p@
fails without consuming input, the terminal result @k@ is returned.

> some = pfoldr1 CONS EMPTY

@since 0.1.0.0
-}
pfoldr1 :: (ParserOps repf, ParserOps repk) => repf (a -> b -> b) -> repk b -> Parser a -> Parser b
pfoldr1 :: repf (a -> b -> b) -> repk b -> Parser a -> Parser b
pfoldr1 repf (a -> b -> b)
f repk b
k Parser a
p = repf (a -> b -> b)
f repf (a -> b -> b) -> Parser a -> Parser (b -> b)
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> Parser a
p Parser (b -> b) -> Parser b -> Parser b
forall a b. Parser (a -> b) -> Parser a -> Parser b
<*> repf (a -> b -> b) -> repk b -> Parser a -> Parser b
forall (repf :: Type -> Type) (repk :: Type -> Type) a b.
(ParserOps repf, ParserOps repk) =>
repf (a -> b -> b) -> repk b -> Parser a -> Parser b
pfoldr repf (a -> b -> b)
f repk b
k Parser a
p

{-|
@pfoldl f k p@ parses __zero__ or more @p@s and combines the results using the function @f@. The
accumulator is initialised with the value @k@.

@since 0.1.0.0
-}
pfoldl :: (ParserOps repf, ParserOps repk) => repf (b -> a -> b) -> repk b -> Parser a -> Parser b
pfoldl :: repf (b -> a -> b) -> repk b -> Parser a -> Parser b
pfoldl repf (b -> a -> b)
f repk b
k Parser a
p = Parser b -> Parser (b -> b) -> Parser b
forall a. Parser a -> Parser (a -> a) -> Parser a
chainPost (repk b -> Parser b
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure repk b
k) ((Defunc ((b -> a -> b) -> a -> b -> b)
forall a b c. Defunc ((a -> b -> c) -> b -> a -> c)
FLIP Defunc ((b -> a -> b) -> a -> b -> b)
-> Parser (b -> a -> b) -> Parser (a -> b -> b)
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> repf (b -> a -> b) -> Parser (b -> a -> b)
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure repf (b -> a -> b)
f) Parser (a -> b -> b) -> Parser a -> Parser (b -> b)
forall a b. Parser (a -> b) -> Parser a -> Parser b
<*> Parser a
p)

{-|
@pfoldl1 f k p@ parses __one__ or more @p@s and combines the results using the function @f@. The
accumulator is initialised with the value @k@.

@since 0.1.0.0
-}
pfoldl1 :: (ParserOps repf, ParserOps repk) => repf (b -> a -> b) -> repk b -> Parser a -> Parser b
pfoldl1 :: repf (b -> a -> b) -> repk b -> Parser a -> Parser b
pfoldl1 repf (b -> a -> b)
f repk b
k Parser a
p = Parser b -> Parser (b -> b) -> Parser b
forall a. Parser a -> Parser (a -> a) -> Parser a
chainPost (repf (b -> a -> b)
f repf (b -> a -> b) -> Parser b -> Parser (a -> b)
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> repk b -> Parser b
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure repk b
k Parser (a -> b) -> Parser a -> Parser b
forall a b. Parser (a -> b) -> Parser a -> Parser b
<*> Parser a
p) ((Defunc ((b -> a -> b) -> a -> b -> b)
forall a b c. Defunc ((a -> b -> c) -> b -> a -> c)
FLIP Defunc ((b -> a -> b) -> a -> b -> b)
-> Parser (b -> a -> b) -> Parser (a -> b -> b)
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> repf (b -> a -> b) -> Parser (b -> a -> b)
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure repf (b -> a -> b)
f) Parser (a -> b -> b) -> Parser a -> Parser (b -> b)
forall a b. Parser (a -> b) -> Parser a -> Parser b
<*> Parser a
p)

-- Chain Combinators
{-|
@chainl1' wrap p op @ parses one or more occurrences of @p@, separated by @op@. Returns a value obtained
by a /left/ associative application of all functions returned by @op@ to the values returned by @p@.
The function @wrap@ is used to transform the initial value from @p@ into the correct form.

@since 0.1.0.0
-}
chainl1' :: ParserOps rep => rep (a -> b) -> Parser a -> Parser (b -> a -> b) -> Parser b
chainl1' :: rep (a -> b) -> Parser a -> Parser (b -> a -> b) -> Parser b
chainl1' rep (a -> b)
f Parser a
p Parser (b -> a -> b)
op = Parser b -> Parser (b -> b) -> Parser b
forall a. Parser a -> Parser (a -> a) -> Parser a
chainPost (rep (a -> b)
f rep (a -> b) -> Parser a -> Parser b
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> Parser a
p) (Defunc ((b -> a -> b) -> a -> b -> b)
forall a b c. Defunc ((a -> b -> c) -> b -> a -> c)
FLIP Defunc ((b -> a -> b) -> a -> b -> b)
-> Parser (b -> a -> b) -> Parser (a -> b -> b)
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> Parser (b -> a -> b)
op Parser (a -> b -> b) -> Parser a -> Parser (b -> b)
forall a b. Parser (a -> b) -> Parser a -> Parser b
<*> Parser a
p)

{-|
The classic version of the left-associative chain combinator. See `chainl1'`.

> chainl1 p op = chainl1' ID p op

@since 0.1.0.0
-}
chainl1 :: Parser a -> Parser (a -> a -> a) -> Parser a
chainl1 :: Parser a -> Parser (a -> a -> a) -> Parser a
chainl1 = Defunc (a -> a) -> Parser a -> Parser (a -> a -> a) -> Parser a
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser (b -> a -> b) -> Parser b
chainl1' Defunc (a -> a)
forall a. Defunc (a -> a)
ID

{-|
@chainr1' wrap p op @ parses one or more occurrences of @p@, separated by @op@. Returns a value obtained
by a /right/ associative application of all functions returned by @op@ to the values returned by @p@.
The function @wrap@ is used to transform the final value from @p@ into the correct form.

@since 0.1.0.0
-}
chainr1' :: ParserOps rep => rep (a -> b) -> Parser a -> Parser (a -> b -> b) -> Parser b
chainr1' :: rep (a -> b) -> Parser a -> Parser (a -> b -> b) -> Parser b
chainr1' rep (a -> b)
f Parser a
p Parser (a -> b -> b)
op = Defunc (b -> b)
-> (forall r. Reg r (b -> b) -> Parser b) -> Parser b
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep a -> (forall r. Reg r a -> Parser b) -> Parser b
newRegister_ Defunc (b -> b)
forall a. Defunc (a -> a)
ID ((forall r. Reg r (b -> b) -> Parser b) -> Parser b)
-> (forall r. Reg r (b -> b) -> Parser b) -> Parser b
forall a b. (a -> b) -> a -> b
$ \Reg r (b -> b)
acc ->
  let go :: Parser b
go = Parser a -> (Parser a -> Parser b) -> Parser b
forall a b. Parser a -> (Parser a -> Parser b) -> Parser b
bind Parser a
p ((Parser a -> Parser b) -> Parser b)
-> (Parser a -> Parser b) -> Parser b
forall a b. (a -> b) -> a -> b
$ \Parser a
x ->
           Reg r (b -> b) -> Parser ((b -> b) -> b -> b) -> Parser ()
forall r a. Reg r a -> Parser (a -> a) -> Parser ()
modify Reg r (b -> b)
acc (Defunc ((b -> b) -> (b -> b) -> b -> b)
-> Defunc ((b -> b) -> (b -> b) -> b -> b)
forall y x a b c.
((x -> y) ~ ((a -> b -> c) -> b -> a -> c)) =>
Defunc x -> Defunc y
FLIP_H Defunc ((b -> b) -> (b -> b) -> b -> b)
forall b c a. Defunc ((b -> c) -> (a -> b) -> a -> c)
COMPOSE Defunc ((b -> b) -> (b -> b) -> b -> b)
-> Parser (b -> b) -> Parser ((b -> b) -> b -> b)
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> (Parser (a -> b -> b)
op Parser (a -> b -> b) -> Parser a -> Parser (b -> b)
forall a b. Parser (a -> b) -> Parser a -> Parser b
<*> Parser a
x)) Parser () -> Parser b -> Parser b
forall a b. Parser a -> Parser b -> Parser b
*> Parser b
go
       Parser b -> Parser b -> Parser b
forall a. Parser a -> Parser a -> Parser a
<|> rep (a -> b)
f rep (a -> b) -> Parser a -> Parser b
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> Parser a
x
  in Parser b
go Parser b -> Parser (b -> b) -> Parser b
forall a b. Parser a -> Parser (a -> b) -> Parser b
<**> Reg r (b -> b) -> Parser (b -> b)
forall r a. Reg r a -> Parser a
get Reg r (b -> b)
acc

{-|
The classic version of the right-associative chain combinator. See `chainr1'`.

> chainr1 p op = chainr1' ID p op

@since 0.1.0.0
-}
chainr1 :: Parser a -> Parser (a -> a -> a) -> Parser a
chainr1 :: Parser a -> Parser (a -> a -> a) -> Parser a
chainr1 = Defunc (a -> a) -> Parser a -> Parser (a -> a -> a) -> Parser a
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser (a -> b -> b) -> Parser b
chainr1' Defunc (a -> a)
forall a. Defunc (a -> a)
ID

{-|
Like `chainr1`, but may parse zero occurences of @p@ in which case the value is returned.

@since 0.1.0.0
-}
chainr :: ParserOps rep => Parser a -> Parser (a -> a -> a) -> rep a -> Parser a
chainr :: Parser a -> Parser (a -> a -> a) -> rep a -> Parser a
chainr Parser a
p Parser (a -> a -> a)
op rep a
x = rep a -> Parser a -> Parser a
forall (rep :: Type -> Type) a.
ParserOps rep =>
rep a -> Parser a -> Parser a
option rep a
x (Parser a -> Parser (a -> a -> a) -> Parser a
forall a. Parser a -> Parser (a -> a -> a) -> Parser a
chainr1 Parser a
p Parser (a -> a -> a)
op)

{-|
Like `chainl1`, but may parse zero occurences of @p@ in which case the value is returned.

@since 0.1.0.0
-}
chainl :: ParserOps rep => Parser a -> Parser (a -> a -> a) -> rep a -> Parser a
chainl :: Parser a -> Parser (a -> a -> a) -> rep a -> Parser a
chainl Parser a
p Parser (a -> a -> a)
op rep a
x = rep a -> Parser a -> Parser a
forall (rep :: Type -> Type) a.
ParserOps rep =>
rep a -> Parser a -> Parser a
option rep a
x (Parser a -> Parser (a -> a -> a) -> Parser a
forall a. Parser a -> Parser (a -> a -> a) -> Parser a
chainl1 Parser a
p Parser (a -> a -> a)
op)

-- Derived Combinators
{-|
Attempts to parse the given parser __zero__ or more times, collecting all of the successful results
into a list. Same as @manyN 0@

@since 0.1.0.0
-}
many :: Parser a -> Parser [a]
many :: Parser a -> Parser [a]
many = Defunc (a -> [a] -> [a]) -> Defunc [a] -> Parser a -> Parser [a]
forall (repf :: Type -> Type) (repk :: Type -> Type) a b.
(ParserOps repf, ParserOps repk) =>
repf (a -> b -> b) -> repk b -> Parser a -> Parser b
pfoldr Defunc (a -> [a] -> [a])
forall a. Defunc (a -> [a] -> [a])
CONS Defunc [a]
forall b. Defunc [b]
EMPTY

{-|
Attempts to parse the given parser __n__ or more times, collecting all of the successful results
into a list.

@since 0.1.0.0
-}
manyN :: Int -> Parser a -> Parser [a]
manyN :: Int -> Parser a -> Parser [a]
manyN Int
n Parser a
p = (Int -> Parser [a] -> Parser [a])
-> Parser [a] -> [Int] -> Parser [a]
forall (t :: Type -> Type) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((Parser [a] -> Parser [a]) -> Int -> Parser [a] -> Parser [a]
forall a b. a -> b -> a
const (Parser a
p Parser a -> Parser [a] -> Parser [a]
forall a. Parser a -> Parser [a] -> Parser [a]
<:>)) (Parser a -> Parser [a]
forall a. Parser a -> Parser [a]
many Parser a
p) [Int
1..Int
n]

{-|
Attempts to parse the given parser __one__ or more times, collecting all of the successful results
into a list. Same as @manyN 1@

@since 0.1.0.0
-}
some :: Parser a -> Parser [a]
some :: Parser a -> Parser [a]
some = Int -> Parser a -> Parser [a]
forall a. Int -> Parser a -> Parser [a]
manyN Int
1

{-|
Like `many`, excepts discards its results.

@since 0.1.0.0
-}
skipMany :: Parser a -> Parser ()
--skipMany p = let skipManyp = p *> skipManyp <|> unit in skipManyp
skipMany :: Parser a -> Parser ()
skipMany = Parser () -> Parser ()
forall a. Parser a -> Parser ()
void (Parser () -> Parser ())
-> (Parser a -> Parser ()) -> Parser a -> Parser ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Defunc (() -> a -> ()) -> Defunc () -> Parser a -> Parser ()
forall (repf :: Type -> Type) (repk :: Type -> Type) b a.
(ParserOps repf, ParserOps repk) =>
repf (b -> a -> b) -> repk b -> Parser a -> Parser b
pfoldl Defunc (() -> a -> ())
forall a b. Defunc (a -> b -> a)
CONST Defunc ()
UNIT -- the void here will encourage the optimiser to recognise that the register is unused

{-|
Like `manyN`, excepts discards its results.

@since 0.1.0.0
-}
skipManyN :: Int -> Parser a -> Parser ()
skipManyN :: Int -> Parser a -> Parser ()
skipManyN Int
n Parser a
p = (Int -> Parser () -> Parser ()) -> Parser () -> [Int] -> Parser ()
forall (t :: Type -> Type) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((Parser () -> Parser ()) -> Int -> Parser () -> Parser ()
forall a b. a -> b -> a
const (Parser a
p Parser a -> Parser () -> Parser ()
forall a b. Parser a -> Parser b -> Parser b
*>)) (Parser a -> Parser ()
forall a. Parser a -> Parser ()
skipMany Parser a
p) [Int
1..Int
n]

{-|
Like `some`, excepts discards its results.

@since 0.1.0.0
-}
skipSome :: Parser a -> Parser ()
skipSome :: Parser a -> Parser ()
skipSome = Int -> Parser a -> Parser ()
forall a. Int -> Parser a -> Parser ()
skipManyN Int
1

{-|
@sepBy p sep@ parses __zero__ or more occurrences of @p@, separated by @sep@.
Returns a list of values returned by @p@.

@since 0.1.0.0
-}
sepBy :: Parser a -> Parser b -> Parser [a]
sepBy :: Parser a -> Parser b -> Parser [a]
sepBy Parser a
p Parser b
sep = Defunc [a] -> Parser [a] -> Parser [a]
forall (rep :: Type -> Type) a.
ParserOps rep =>
rep a -> Parser a -> Parser a
option Defunc [a]
forall b. Defunc [b]
EMPTY (Parser a -> Parser b -> Parser [a]
forall a b. Parser a -> Parser b -> Parser [a]
sepBy1 Parser a
p Parser b
sep)

{-|
@sepBy1 p sep@ parses __one__ or more occurrences of @p@, separated by @sep@.
Returns a list of values returned by @p@.

@since 0.1.0.0
-}
sepBy1 :: Parser a -> Parser b -> Parser [a]
sepBy1 :: Parser a -> Parser b -> Parser [a]
sepBy1 Parser a
p Parser b
sep = Parser a
p Parser a -> Parser [a] -> Parser [a]
forall a. Parser a -> Parser [a] -> Parser [a]
<:> Parser a -> Parser [a]
forall a. Parser a -> Parser [a]
many (Parser b
sep Parser b -> Parser a -> Parser a
forall a b. Parser a -> Parser b -> Parser b
*> Parser a
p)

{-|
@endBy p sep@ parses __zero__ or more occurrences of @p@, separated and ended by @sep@.
Returns a list of values returned by @p@.

@since 0.1.0.0
-}
endBy :: Parser a -> Parser b -> Parser [a]
endBy :: Parser a -> Parser b -> Parser [a]
endBy Parser a
p Parser b
sep = Parser a -> Parser [a]
forall a. Parser a -> Parser [a]
many (Parser a
p Parser a -> Parser b -> Parser a
forall a b. Parser a -> Parser b -> Parser a
<* Parser b
sep)

{-|
@endBy1 p sep@ parses __one__ or more occurrences of @p@, separated and ended by @sep@.
Returns a list of values returned by @p@.

@since 0.1.0.0
-}
endBy1 :: Parser a -> Parser b -> Parser [a]
endBy1 :: Parser a -> Parser b -> Parser [a]
endBy1 Parser a
p Parser b
sep = Parser a -> Parser [a]
forall a. Parser a -> Parser [a]
some (Parser a
p Parser a -> Parser b -> Parser a
forall a b. Parser a -> Parser b -> Parser a
<* Parser b
sep)

{-|
@sepEndBy p sep@ parses __zero__ or more occurrences of @p@, separated and /optionally/ ended by @sep@.
Returns a list of values returned by @p@.

@since 0.1.0.0
-}
sepEndBy :: Parser a -> Parser b -> Parser [a]
sepEndBy :: Parser a -> Parser b -> Parser [a]
sepEndBy Parser a
p Parser b
sep = Defunc [a] -> Parser [a] -> Parser [a]
forall (rep :: Type -> Type) a.
ParserOps rep =>
rep a -> Parser a -> Parser a
option Defunc [a]
forall b. Defunc [b]
EMPTY (Parser a -> Parser b -> Parser [a]
forall a b. Parser a -> Parser b -> Parser [a]
sepEndBy1 Parser a
p Parser b
sep)

{-|
@sepEndBy1 p sep@ parses __one__ or more occurrences of @p@, separated and /optionally/ ended by @sep@.
Returns a list of values returned by @p@.

@since 0.1.0.0
-}
sepEndBy1 :: Parser a -> Parser b -> Parser [a]
sepEndBy1 :: Parser a -> Parser b -> Parser [a]
sepEndBy1 Parser a
p Parser b
sep = Defunc ([a] -> [a])
-> (forall r. Reg r ([a] -> [a]) -> Parser [a]) -> Parser [a]
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep a -> (forall r. Reg r a -> Parser b) -> Parser b
newRegister_ Defunc ([a] -> [a])
forall a. Defunc (a -> a)
ID ((forall r. Reg r ([a] -> [a]) -> Parser [a]) -> Parser [a])
-> (forall r. Reg r ([a] -> [a]) -> Parser [a]) -> Parser [a]
forall a b. (a -> b) -> a -> b
$ \Reg r ([a] -> [a])
acc ->
  let go :: Parser ([a] -> [a])
go = Reg r ([a] -> [a])
-> Parser (([a] -> [a]) -> [a] -> [a]) -> Parser ()
forall r a. Reg r a -> Parser (a -> a) -> Parser ()
modify Reg r ([a] -> [a])
acc (Defunc (([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a])
-> Defunc (a -> [a] -> [a])
-> Defunc (a -> ([a] -> [a]) -> [a] -> [a])
forall z x y b c a.
((x -> y -> z) ~ ((b -> c) -> (a -> b) -> a -> c)) =>
Defunc x -> Defunc y -> Defunc z
COMPOSE_H (Defunc (([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a])
-> Defunc (([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a])
forall y x a b c.
((x -> y) ~ ((a -> b -> c) -> b -> a -> c)) =>
Defunc x -> Defunc y
FLIP_H Defunc (([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a])
forall b c a. Defunc ((b -> c) -> (a -> b) -> a -> c)
COMPOSE) Defunc (a -> [a] -> [a])
forall a. Defunc (a -> [a] -> [a])
CONS Defunc (a -> ([a] -> [a]) -> [a] -> [a])
-> Parser a -> Parser (([a] -> [a]) -> [a] -> [a])
forall (rep :: Type -> Type) a b.
ParserOps rep =>
rep (a -> b) -> Parser a -> Parser b
<$> Parser a
p)
         Parser () -> Parser ([a] -> [a]) -> Parser ([a] -> [a])
forall a b. Parser a -> Parser b -> Parser b
*> (Parser b
sep Parser b -> Parser ([a] -> [a]) -> Parser ([a] -> [a])
forall a b. Parser a -> Parser b -> Parser b
*> (Parser ([a] -> [a])
go Parser ([a] -> [a]) -> Parser ([a] -> [a]) -> Parser ([a] -> [a])
forall a. Parser a -> Parser a -> Parser a
<|> Reg r ([a] -> [a]) -> Parser ([a] -> [a])
forall r a. Reg r a -> Parser a
get Reg r ([a] -> [a])
acc) Parser ([a] -> [a]) -> Parser ([a] -> [a]) -> Parser ([a] -> [a])
forall a. Parser a -> Parser a -> Parser a
<|> Reg r ([a] -> [a]) -> Parser ([a] -> [a])
forall r a. Reg r a -> Parser a
get Reg r ([a] -> [a])
acc)
  in Parser ([a] -> [a])
go Parser ([a] -> [a]) -> Parser [a] -> Parser [a]
forall a b. Parser (a -> b) -> Parser a -> Parser b
<*> Defunc [a] -> Parser [a]
forall (rep :: Type -> Type) a. ParserOps rep => rep a -> Parser a
pure Defunc [a]
forall b. Defunc [b]
EMPTY

{-sepEndBy1 :: Parser a -> Parser b -> Parser [a]
sepEndBy1 p sep =
  let seb1 = p <**> (sep *> (FLIP_H CONS <$> option EMPTY seb1)
                 <|> pure (APP_H (FLIP_H CONS) EMPTY))
  in seb1-}