{-# LANGUAGE  RankNTypes, 
              GADTs,
              MultiParamTypeClasses,
              FunctionalDependencies, 
              FlexibleInstances, 
              FlexibleContexts, 
              UndecidableInstances,
              NoMonomorphismRestriction #-}

-- | This module contains a large variety of combinators for list-like structures. the extension @_ng@ indicates that 
--   that variant is the non-greedy variant.
--   See the "Text.ParserCombinators.UU.Demo.Examples" module for some examples of their use.

module Text.ParserCombinators.UU.Derived where
import Text.ParserCombinators.UU.Core

-- * Some aliases for oft occurring constructs

-- | @`pReturn`@ is defined for upwards compatibility
--
pReturn :: Applicative p => a -> p  a
pReturn :: a -> p a
pReturn  = a -> p a
forall (f :: * -> *) a. Applicative f => a -> f a
pure

-- | @`pFail`@ is defined for upwards compatibility, and is the unit for @<|>@
--
pFail :: Alternative  p => p  a
pFail :: p a
pFail    = p a
forall (f :: * -> *) a. Alternative f => f a
empty

-- | `pMaybe` greedily recognises its argument. If not @Nothing@ is returned.
--
pMaybe :: IsParser p => p a -> p (Maybe a)
pMaybe :: p a -> p (Maybe a)
pMaybe p a
p = String -> p a -> p (Maybe a) -> p (Maybe a)
forall (p :: * -> *) a c.
ExtAlternative p =>
String -> p a -> c -> c
must_be_non_empty String
"pMaybe" p a
p (a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> p a -> p (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p a
p p (Maybe a) -> Maybe a -> p (Maybe a)
forall (p :: * -> *) a. ExtAlternative p => p a -> a -> p a
`opt` Maybe a
forall a. Maybe a
Nothing) 

-- | `pEither` recognises either one of its arguments.
--
pEither :: IsParser p => p a -> p b -> p (Either a b)
pEither :: p a -> p b -> p (Either a b)
pEither p a
p p b
q = a -> Either a b
forall a b. a -> Either a b
Left (a -> Either a b) -> p a -> p (Either a b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p a
p p (Either a b) -> p (Either a b) -> p (Either a b)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> b -> Either a b
forall a b. b -> Either a b
Right (b -> Either a b) -> p b -> p (Either a b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p b
q
                                                
-- | `<$$>` is the version of `<$>` which flips the function argument 
--
(<$$>)    ::  IsParser p => (a -> b -> c) -> p b -> p (a -> c)
a -> b -> c
f <$$> :: (a -> b -> c) -> p b -> p (a -> c)
<$$> p b
p  =  (a -> b -> c) -> b -> a -> c
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> b -> c
f (b -> a -> c) -> p b -> p (a -> c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p b
p

-- | `<??>` parses an optional postfix element and applies its result to its left hand result
--
(<??>) :: IsParser p => p a -> p (a -> a) -> p a
p a
p <??> :: p a -> p (a -> a) -> p a
<??> p (a -> a)
q        = String -> p (a -> a) -> p a -> p a
forall (p :: * -> *) a c.
ExtAlternative p =>
String -> p a -> c -> c
must_be_non_empty String
"<??>" p (a -> a)
q (p a
p p a -> p (a -> a) -> p a
forall (f :: * -> *) a b. Applicative f => f a -> f (a -> b) -> f b
<**> (p (a -> a)
q p (a -> a) -> (a -> a) -> p (a -> a)
forall (p :: * -> *) a. ExtAlternative p => p a -> a -> p a
`opt` a -> a
forall a. a -> a
id))


-- | `<.>` functional composition of two parsers
--
(<.>) :: IsParser p => p (b -> c) -> p (a -> b) -> p (a -> c)
p (b -> c)
f <.> :: p (b -> c) -> p (a -> b) -> p (a -> c)
<.> p (a -> b)
g = (b -> c) -> (a -> b) -> a -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) ((b -> c) -> (a -> b) -> a -> c)
-> p (b -> c) -> p ((a -> b) -> a -> c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p (b -> c)
f p ((a -> b) -> a -> c) -> p (a -> b) -> p (a -> c)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> p (a -> b)
g

-- | `<..>` functional composition of two parsers with the arguments reversed
--
(<..>) :: IsParser p => p (a -> b) -> p (b -> c) -> p (a -> c)
p (a -> b)
g <..> :: p (a -> b) -> p (b -> c) -> p (a -> c)
<..> p (b -> c)
f = (b -> c) -> (a -> b) -> a -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) ((b -> c) -> (a -> b) -> a -> c)
-> p (b -> c) -> p ((a -> b) -> a -> c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p (b -> c)
f p ((a -> b) -> a -> c) -> p (a -> b) -> p (a -> c)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> p (a -> b)
g


infixl 4  <??>

-- | `pMany` is equivalent to the `many` from "Control.Applicative". We want however all our parsers to start with a lower case @p@.
pMany :: IsParser p => p a -> p [a]
pMany :: p a -> p [a]
pMany p a
p = p a -> p [a]
forall (p :: * -> *) a. IsParser p => p a -> p [a]
pList p a
p

-- | `pSome` is equivalent to the `some` from "Control.Applicative". We want however all our parsers to start with a lower case @p@.
pSome :: (IsParser f) => f a -> f [a]
pSome :: f a -> f [a]
pSome f a
p = (:) (a -> [a] -> [a]) -> f a -> f ([a] -> [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f a
p f ([a] -> [a]) -> f [a] -> f [a]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> f a -> f [a]
forall (p :: * -> *) a. IsParser p => p a -> p [a]
pList f a
p


-- | @`pPacked`@ surrounds its third parser with the first and the second one, returning only the middle result
pPacked :: IsParser p => p b1 -> p b2 -> p a -> p a
pPacked :: p b1 -> p b2 -> p a -> p a
pPacked p b1
l p b2
r p a
x   =   p b1
l p b1 -> p a -> p a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*>  p a
x p a -> p b2 -> p a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<*   p b2
r

-- * Iterating combinators, all in a greedy (default) and a non-greedy (ending with @_ng@) variant

-- ** Recognising  list like structures
pFoldr    :: IsParser p => (a -> a1 -> a1, a1) -> p a -> p a1
pFoldr :: (a -> a1 -> a1, a1) -> p a -> p a1
pFoldr         alg :: (a -> a1 -> a1, a1)
alg@(a -> a1 -> a1
op,a1
e)     p a
p =  String -> p a -> p a1 -> p a1
forall (p :: * -> *) a c.
ExtAlternative p =>
String -> p a -> c -> c
must_be_non_empty String
"pFoldr" p a
p p a1
pfm
                                   where pfm :: p a1
pfm = (a -> a1 -> a1
op (a -> a1 -> a1) -> p a -> p (a1 -> a1)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p a
p p (a1 -> a1) -> p a1 -> p a1
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> p a1
pfm) p a1 -> a1 -> p a1
forall (p :: * -> *) a. ExtAlternative p => p a -> a -> p a
`opt` a1
e

pFoldr_ng ::  IsParser p => (a -> a1 -> a1, a1) -> p a -> p a1
pFoldr_ng :: (a -> a1 -> a1, a1) -> p a -> p a1
pFoldr_ng      alg :: (a -> a1 -> a1, a1)
alg@(a -> a1 -> a1
op,a1
e)     p a
p =  String -> p a -> p a1 -> p a1
forall (p :: * -> *) a c.
ExtAlternative p =>
String -> p a -> c -> c
must_be_non_empty String
"pFoldr_ng" p a
p p a1
pfm 
                                   where pfm :: p a1
pfm = (a -> a1 -> a1
op (a -> a1 -> a1) -> p a -> p (a1 -> a1)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p a
p p (a1 -> a1) -> p a1 -> p a1
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> p a1
pfm)  p a1 -> p a1 -> p a1
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> a1 -> p a1
forall (f :: * -> *) a. Applicative f => a -> f a
pure a1
e


pFoldr1    :: IsParser p => (v -> b -> b, b) -> p v -> p b
pFoldr1 :: (v -> b -> b, b) -> p v -> p b
pFoldr1        alg :: (v -> b -> b, b)
alg@(v -> b -> b
op,b
e)     p v
p =  String -> p v -> p b -> p b
forall (p :: * -> *) a c.
ExtAlternative p =>
String -> p a -> c -> c
must_be_non_empty String
"pFoldr1"    p v
p (v -> b -> b
op (v -> b -> b) -> p v -> p (b -> b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p v
p p (b -> b) -> p b -> p b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (v -> b -> b, b) -> p v -> p b
forall (p :: * -> *) a a1.
IsParser p =>
(a -> a1 -> a1, a1) -> p a -> p a1
pFoldr     (v -> b -> b, b)
alg p v
p) 

pFoldr1_ng ::  IsParser p => (v -> b -> b, b) -> p v -> p b
pFoldr1_ng :: (v -> b -> b, b) -> p v -> p b
pFoldr1_ng     alg :: (v -> b -> b, b)
alg@(v -> b -> b
op,b
e)     p v
p =  String -> p v -> p b -> p b
forall (p :: * -> *) a c.
ExtAlternative p =>
String -> p a -> c -> c
must_be_non_empty String
"pFoldr1_ng" p v
p (v -> b -> b
op (v -> b -> b) -> p v -> p (b -> b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p v
p p (b -> b) -> p b -> p b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (v -> b -> b, b) -> p v -> p b
forall (p :: * -> *) a a1.
IsParser p =>
(a -> a1 -> a1, a1) -> p a -> p a1
pFoldr_ng  (v -> b -> b, b)
alg p v
p)


list_alg :: (a -> [a] -> [a], [a1])
list_alg :: (a -> [a] -> [a], [a1])
list_alg = ((:), [])

pList    ::    IsParser p => p a -> p [a]
pList :: p a -> p [a]
pList         p a
p =  String -> p a -> p [a] -> p [a]
forall (p :: * -> *) a c.
ExtAlternative p =>
String -> p a -> c -> c
must_be_non_empty String
"pList"    p a
p ((a -> [a] -> [a], [a]) -> p a -> p [a]
forall (p :: * -> *) a a1.
IsParser p =>
(a -> a1 -> a1, a1) -> p a -> p a1
pFoldr        (a -> [a] -> [a], [a])
forall a a1. (a -> [a] -> [a], [a1])
list_alg   p a
p)
pList_ng ::    IsParser p => p a -> p [a]
pList_ng :: p a -> p [a]
pList_ng      p a
p =  String -> p a -> p [a] -> p [a]
forall (p :: * -> *) a c.
ExtAlternative p =>
String -> p a -> c -> c
must_be_non_empty String
"pList_ng" p a
p ((a -> [a] -> [a], [a]) -> p a -> p [a]
forall (p :: * -> *) a a1.
IsParser p =>
(a -> a1 -> a1, a1) -> p a -> p a1
pFoldr_ng     (a -> [a] -> [a], [a])
forall a a1. (a -> [a] -> [a], [a1])
list_alg   p a
p)

pList1    ::  IsParser p =>  p a -> p [a]
pList1 :: p a -> p [a]
pList1         p a
p =  String -> p a -> p [a] -> p [a]
forall (p :: * -> *) a c.
ExtAlternative p =>
String -> p a -> c -> c
must_be_non_empty String
"pList"    p a
p ((a -> [a] -> [a], [a]) -> p a -> p [a]
forall (p :: * -> *) a a1.
IsParser p =>
(a -> a1 -> a1, a1) -> p a -> p a1
pFoldr1       (a -> [a] -> [a], [a])
forall a a1. (a -> [a] -> [a], [a1])
list_alg   p a
p)
pList1_ng ::   IsParser p => p a -> p [a]
pList1_ng :: p a -> p [a]
pList1_ng      p a
p =  String -> p a -> p [a] -> p [a]
forall (p :: * -> *) a c.
ExtAlternative p =>
String -> p a -> c -> c
must_be_non_empty String
"pList_ng" p a
p ((a -> [a] -> [a], [a]) -> p a -> p [a]
forall (p :: * -> *) a a1.
IsParser p =>
(a -> a1 -> a1, a1) -> p a -> p a1
pFoldr1_ng    (a -> [a] -> [a], [a])
forall a a1. (a -> [a] -> [a], [a1])
list_alg   p a
p)

-- * Recognising list structures with separators

pFoldrSep    ::  IsParser p => (v -> b -> b, b) -> p a -> p v -> p b
pFoldrSep :: (v -> b -> b, b) -> p a -> p v -> p b
pFoldrSep      alg :: (v -> b -> b, b)
alg@(v -> b -> b
op,b
e) p a
sep p v
p =  String -> p a -> p v -> p b -> p b
forall (p :: * -> *) a b c.
ExtAlternative p =>
String -> p a -> p b -> c -> c
must_be_non_empties String
"pFoldrSep" p a
sep   p v
p
                                   (v -> b -> b
op (v -> b -> b) -> p v -> p (b -> b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p v
p p (b -> b) -> p b -> p b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (v -> b -> b, b) -> p v -> p b
forall (p :: * -> *) a a1.
IsParser p =>
(a -> a1 -> a1, a1) -> p a -> p a1
pFoldr    (v -> b -> b, b)
alg p v
sepp p b -> b -> p b
forall (p :: * -> *) a. ExtAlternative p => p a -> a -> p a
`opt` b
e)
                                   where sepp :: p v
sepp = p a
sep p a -> p v -> p v
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> p v
p
pFoldrSep_ng ::  IsParser p => (v -> b -> b, b) -> p a -> p v -> p b
pFoldrSep_ng :: (v -> b -> b, b) -> p a -> p v -> p b
pFoldrSep_ng   alg :: (v -> b -> b, b)
alg@(v -> b -> b
op,b
e) p a
sep p v
p =  String -> p a -> p v -> p b -> p b
forall (p :: * -> *) a b c.
ExtAlternative p =>
String -> p a -> p b -> c -> c
must_be_non_empties String
"pFoldrSep" p a
sep   p v
p
                                   (v -> b -> b
op (v -> b -> b) -> p v -> p (b -> b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p v
p p (b -> b) -> p b -> p b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (v -> b -> b, b) -> p v -> p b
forall (p :: * -> *) a a1.
IsParser p =>
(a -> a1 -> a1, a1) -> p a -> p a1
pFoldr_ng (v -> b -> b, b)
alg p v
sepp p b -> p b -> p b
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>  b -> p b
forall (f :: * -> *) a. Applicative f => a -> f a
pure b
e)
                                   where sepp :: p v
sepp = p a
sep p a -> p v -> p v
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> p v
p

pFoldr1Sep    ::   IsParser p => (a -> b -> b, b) -> p a1 ->p a -> p b
pFoldr1Sep :: (a -> b -> b, b) -> p a1 -> p a -> p b
pFoldr1Sep     alg :: (a -> b -> b, b)
alg@(a -> b -> b
op,b
e) p a1
sep p a
p =  String -> p a1 -> p a -> p b -> p b
forall (p :: * -> *) a b c.
ExtAlternative p =>
String -> p a -> p b -> c -> c
must_be_non_empties String
"pFoldr1Sep"    p a1
sep   p a
p p b
pfm
                                   where pfm :: p b
pfm = a -> b -> b
op (a -> b -> b) -> p a -> p (b -> b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p a
p p (b -> b) -> p b -> p b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (a -> b -> b, b) -> p a -> p b
forall (p :: * -> *) a a1.
IsParser p =>
(a -> a1 -> a1, a1) -> p a -> p a1
pFoldr    (a -> b -> b, b)
alg (p a1
sep p a1 -> p a -> p a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> p a
p)
pFoldr1Sep_ng ::   IsParser p => (a -> b -> b, b) -> p a1 ->p a -> p b
pFoldr1Sep_ng :: (a -> b -> b, b) -> p a1 -> p a -> p b
pFoldr1Sep_ng  alg :: (a -> b -> b, b)
alg@(a -> b -> b
op,b
e) p a1
sep p a
p =  String -> p a1 -> p a -> p b -> p b
forall (p :: * -> *) a b c.
ExtAlternative p =>
String -> p a -> p b -> c -> c
must_be_non_empties String
"pFoldr1Sep_ng" p a1
sep   p a
p p b
pfm 
                                   where pfm :: p b
pfm = a -> b -> b
op (a -> b -> b) -> p a -> p (b -> b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p a
p p (b -> b) -> p b -> p b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (a -> b -> b, b) -> p a -> p b
forall (p :: * -> *) a a1.
IsParser p =>
(a -> a1 -> a1, a1) -> p a -> p a1
pFoldr_ng (a -> b -> b, b)
alg (p a1
sep p a1 -> p a -> p a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> p a
p)

pListSep    :: IsParser p => p a1 -> p a -> p [a]
pListSep :: p a1 -> p a -> p [a]
pListSep      p a1
sep p a
p = String -> p a1 -> p a -> p [a] -> p [a]
forall (p :: * -> *) a b c.
ExtAlternative p =>
String -> p a -> p b -> c -> c
must_be_non_empties String
"pListSep"    p a1
sep   p a
p ((a -> [a] -> [a], [a]) -> p a1 -> p a -> p [a]
forall (p :: * -> *) v b a.
IsParser p =>
(v -> b -> b, b) -> p a -> p v -> p b
pFoldrSep     (a -> [a] -> [a], [a])
forall a a1. (a -> [a] -> [a], [a1])
list_alg p a1
sep p a
p)
pListSep_ng :: IsParser p => p a1 -> p a -> p [a]
pListSep_ng :: p a1 -> p a -> p [a]
pListSep_ng   p a1
sep p a
p = String
-> p a1
-> p a
-> ((a -> [a] -> [a], [a]) -> p a1 -> p a -> p [a])
-> (a -> [a] -> [a], [a])
-> p a1
-> p a
-> p [a]
forall (p :: * -> *) a b c.
ExtAlternative p =>
String -> p a -> p b -> c -> c
must_be_non_empties String
"pListSep_ng" p a1
sep   p a
p (a -> [a] -> [a], [a]) -> p a1 -> p a -> p [a]
forall (p :: * -> *) v b a.
IsParser p =>
(v -> b -> b, b) -> p a -> p v -> p b
pFoldrSep_ng  (a -> [a] -> [a], [a])
forall a a1. (a -> [a] -> [a], [a1])
list_alg p a1
sep p a
p

pList1Sep    :: IsParser p => p a1 -> p a -> p [a]
pList1Sep :: p a1 -> p a -> p [a]
pList1Sep     p a1
s p a
p =  String -> p a1 -> p a -> p [a] -> p [a]
forall (p :: * -> *) a b c.
ExtAlternative p =>
String -> p a -> p b -> c -> c
must_be_non_empties String
"pListSep"    p a1
s   p a
p ((a -> [a] -> [a], [a]) -> p a1 -> p a -> p [a]
forall (p :: * -> *) v b a.
IsParser p =>
(v -> b -> b, b) -> p a -> p v -> p b
pFoldr1Sep    (a -> [a] -> [a], [a])
forall a a1. (a -> [a] -> [a], [a1])
list_alg p a1
s p a
p)
pList1Sep_ng :: IsParser p => p a1 -> p a -> p [a]
pList1Sep_ng :: p a1 -> p a -> p [a]
pList1Sep_ng  p a1
s p a
p =  String -> p a1 -> p a -> p [a] -> p [a]
forall (p :: * -> *) a b c.
ExtAlternative p =>
String -> p a -> p b -> c -> c
must_be_non_empties String
"pListSep_ng" p a1
s   p a
p ((a -> [a] -> [a], [a]) -> p a1 -> p a -> p [a]
forall (p :: * -> *) v b a.
IsParser p =>
(v -> b -> b, b) -> p a -> p v -> p b
pFoldr1Sep_ng (a -> [a] -> [a], [a])
forall a a1. (a -> [a] -> [a], [a1])
list_alg p a1
s p a
p)

-- * Combinators for chained structures
-- ** Treating the operator as right associative
pChainr    :: IsParser p => p (c -> c -> c) -> p c -> p c
pChainr :: p (c -> c -> c) -> p c -> p c
pChainr    p (c -> c -> c)
op p c
x    =   String -> p (c -> c -> c) -> p c -> p c -> p c
forall (p :: * -> *) a b c.
ExtAlternative p =>
String -> p a -> p b -> c -> c
must_be_non_empties String
"pChainr"    p (c -> c -> c)
op   p c
x p c
r where r :: p c
r = p c
x p c -> p (c -> c) -> p c
forall (p :: * -> *) a. IsParser p => p a -> p (a -> a) -> p a
<??> ((c -> c -> c) -> c -> c -> c
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((c -> c -> c) -> c -> c -> c)
-> p (c -> c -> c) -> p (c -> c -> c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p (c -> c -> c)
op p (c -> c -> c) -> p c -> p (c -> c)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> p c
r)
pChainr_ng :: IsParser p => p (c -> c -> c) -> p c -> p c
pChainr_ng :: p (c -> c -> c) -> p c -> p c
pChainr_ng p (c -> c -> c)
op p c
x    =   String -> p (c -> c -> c) -> p c -> p c -> p c
forall (p :: * -> *) a b c.
ExtAlternative p =>
String -> p a -> p b -> c -> c
must_be_non_empties String
"pChainr_ng" p (c -> c -> c)
op   p c
x p c
r where r :: p c
r = p c
x p c -> p (c -> c) -> p c
forall (f :: * -> *) a b. Applicative f => f a -> f (a -> b) -> f b
<**> (((c -> c -> c) -> c -> c -> c
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((c -> c -> c) -> c -> c -> c)
-> p (c -> c -> c) -> p (c -> c -> c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p (c -> c -> c)
op p (c -> c -> c) -> p c -> p (c -> c)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> p c
r)  p (c -> c) -> p (c -> c) -> p (c -> c)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (c -> c) -> p (c -> c)
forall (f :: * -> *) a. Applicative f => a -> f a
pure c -> c
forall a. a -> a
id)

-- ** Treating the operator as left associative
pChainl    :: IsParser p => p (c -> c -> c) -> p c -> p c
pChainl :: p (c -> c -> c) -> p c -> p c
pChainl   p (c -> c -> c)
op p c
x    =  String -> p (c -> c -> c) -> p c -> p c -> p c
forall (p :: * -> *) a b c.
ExtAlternative p =>
String -> p a -> p b -> c -> c
must_be_non_empties String
"pChainl"    p (c -> c -> c)
op   p c
x (c -> [c -> c] -> c
forall t. t -> [t -> t] -> t
f (c -> [c -> c] -> c) -> p c -> p ([c -> c] -> c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p c
x p ([c -> c] -> c) -> p [c -> c] -> p c
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> p (c -> c) -> p [c -> c]
forall (p :: * -> *) a. IsParser p => p a -> p [a]
pList ((c -> c -> c) -> c -> c -> c
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((c -> c -> c) -> c -> c -> c)
-> p (c -> c -> c) -> p (c -> c -> c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p (c -> c -> c)
op p (c -> c -> c) -> p c -> p (c -> c)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> p c
x)) 
                    where  f :: t -> [t -> t] -> t
f t
x [] = t
x
                           f t
x (t -> t
func:[t -> t]
rest) = t -> [t -> t] -> t
f (t -> t
func t
x) [t -> t]
rest
pChainl_ng :: IsParser p => p (c -> c -> c) -> p c -> p c
pChainl_ng :: p (c -> c -> c) -> p c -> p c
pChainl_ng p (c -> c -> c)
op p c
x    = String -> p (c -> c -> c) -> p c -> p c -> p c
forall (p :: * -> *) a b c.
ExtAlternative p =>
String -> p a -> p b -> c -> c
must_be_non_empties String
"pChainl_ng" p (c -> c -> c)
op   p c
x (c -> [c -> c] -> c
forall t. t -> [t -> t] -> t
f (c -> [c -> c] -> c) -> p c -> p ([c -> c] -> c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p c
x p ([c -> c] -> c) -> p [c -> c] -> p c
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> p (c -> c) -> p [c -> c]
forall (p :: * -> *) a. IsParser p => p a -> p [a]
pList_ng ((c -> c -> c) -> c -> c -> c
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((c -> c -> c) -> c -> c -> c)
-> p (c -> c -> c) -> p (c -> c -> c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p (c -> c -> c)
op p (c -> c -> c) -> p c -> p (c -> c)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> p c
x))
                     where f :: t -> [t -> t] -> t
f t
x [] = t
x
                           f t
x (t -> t
func:[t -> t]
rest) = t -> [t -> t] -> t
f (t -> t
func t
x) [t -> t]
rest

-- * Repeating parsers

-- | `pExact` recognises a specified number of elements
pExact :: (IsParser f) => Int -> f a -> f [a]
pExact :: Int -> f a -> f [a]
pExact Int
n f a
p | Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = [a] -> f [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
           | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>  Int
0 = (:) (a -> [a] -> [a]) -> f a -> f ([a] -> [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f a
p f ([a] -> [a]) -> f [a] -> f [a]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> f a -> f [a]
forall (f :: * -> *) a. IsParser f => Int -> f a -> f [a]
pExact (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) f a
p

pBetween :: (IsParser f) => Int -> Int -> f a -> f [a]
pBetween :: Int -> Int -> f a -> f [a]
pBetween Int
m Int
n f a
p |  Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
m Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<Int
0 =  String -> f [a]
forall a. HasCallStack => String -> a
error String
"negative arguments to pBwteeen"
               |  Int
m Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
n         =  f [a]
forall (f :: * -> *) a. Alternative f => f a
empty
               |  Bool
otherwise     =  [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
(++) ([a] -> [a] -> [a]) -> f [a] -> f ([a] -> [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> f a -> f [a]
forall (f :: * -> *) a. IsParser f => Int -> f a -> f [a]
pExact Int
m f a
p f ([a] -> [a]) -> f [a] -> f [a]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> f a -> f [a]
forall (f :: * -> *) a. IsParser f => Int -> f a -> f [a]
pAtMost (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
m) f a
p

pAtLeast ::  (IsParser f) => Int -> f a -> f [a]
pAtLeast :: Int -> f a -> f [a]
pAtLeast Int
n f a
p  = [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
(++) ([a] -> [a] -> [a]) -> f [a] -> f ([a] -> [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> f a -> f [a]
forall (f :: * -> *) a. IsParser f => Int -> f a -> f [a]
pExact Int
n f a
p f ([a] -> [a]) -> f [a] -> f [a]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> f a -> f [a]
forall (p :: * -> *) a. IsParser p => p a -> p [a]
pList f a
p

pAtMost ::  (IsParser f) => Int -> f a -> f [a]
pAtMost :: Int -> f a -> f [a]
pAtMost Int
n f a
p | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0  = (:) (a -> [a] -> [a]) -> f a -> f ([a] -> [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f a
p f ([a] -> [a]) -> f [a] -> f [a]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> f a -> f [a]
forall (f :: * -> *) a. IsParser f => Int -> f a -> f [a]
pAtMost (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) f a
p f [a] -> [a] -> f [a]
forall (p :: * -> *) a. ExtAlternative p => p a -> a -> p a
`opt`  []
            | Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = [a] -> f [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure []

-- * Counting Parser
-- | Count the number of times @p@ has succeeded
pCount :: (IsParser p, Num b) => p a -> p b
pCount :: p a -> p b
pCount p a
p = (\a
_ b
b -> b
bb -> b -> b
forall a. Num a => a -> a -> a
+b
1) (a -> b -> b) -> p a -> p (b -> b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> p a
p p (b -> b) -> p b -> p b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> p a -> p b
forall (p :: * -> *) b a. (IsParser p, Num b) => p a -> p b
pCount p a
p  p b -> b -> p b
forall (p :: * -> *) a. ExtAlternative p => p a -> a -> p a
`opt` b
0

-- * Miscelleneous 
-- | Build a parser for each element in the argument list and try them all.
pAny :: IsParser p => (a -> p a1) -> [a] -> p a1
pAny :: (a -> p a1) -> [a] -> p a1
pAny  a -> p a1
f [a]
l =  (p a1 -> p a1 -> p a1) -> p a1 -> [p a1] -> p a1
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr p a1 -> p a1 -> p a1
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>) p a1
forall (p :: * -> *) a. Alternative p => p a
pFail ((a -> p a1) -> [a] -> [p a1]
forall a b. (a -> b) -> [a] -> [b]
map a -> p a1
f [a]
l)

-- | pSym was removed because the class Provides was eliminated
-- pAnySym :: Provides st s s => [s] -> P st s
-- pAnySym = pAny pSym