{-# LANGUAGE BangPatterns #-}
module Control.Monad.Combinators
  ( 
    (C.<|>),
    
    C.optional,
    
    C.empty,
    
    
    C.between,
    C.choice,
    count,
    count',
    C.eitherP,
    endBy,
    endBy1,
    many,
    manyTill,
    manyTill_,
    some,
    someTill,
    someTill_,
    C.option,
    sepBy,
    sepBy1,
    sepEndBy,
    sepEndBy1,
    skipMany,
    skipSome,
    skipCount,
    skipManyTill,
    skipSomeTill,
  )
where
import qualified Control.Applicative.Combinators as C
import Control.Monad
count :: Monad m => Int -> m a -> m [a]
count :: forall (m :: * -> *) a. Monad m => Int -> m a -> m [a]
count Int
n' m a
p = ([a] -> [a]) -> Int -> m [a]
forall {t} {c}. (Ord t, Num t) => ([a] -> c) -> t -> m c
go [a] -> [a]
forall a. a -> a
id Int
n'
  where
    go :: ([a] -> c) -> t -> m c
go [a] -> c
f !t
n =
      if t
n t -> t -> Bool
forall a. Ord a => a -> a -> Bool
<= t
0
        then c -> m c
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([a] -> c
f [])
        else do
          a
x <- m a
p
          ([a] -> c) -> t -> m c
go ([a] -> c
f ([a] -> c) -> ([a] -> [a]) -> [a] -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
:)) (t
n t -> t -> t
forall a. Num a => a -> a -> a
- t
1)
{-# INLINE count #-}
count' :: MonadPlus m => Int -> Int -> m a -> m [a]
count' :: forall (m :: * -> *) a. MonadPlus m => Int -> Int -> m a -> m [a]
count' Int
m' Int
n' m a
p =
  if Int
n' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& Int
n' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
m'
    then ([a] -> [a]) -> Int -> m [a]
forall {t} {b}. (Ord t, Num t) => ([a] -> b) -> t -> m b
gom [a] -> [a]
forall a. a -> a
id Int
m'
    else [a] -> m [a]
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return []
  where
    gom :: ([a] -> b) -> t -> m b
gom [a] -> b
f !t
m =
      if t
m t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
0
        then do
          a
x <- m a
p
          ([a] -> b) -> t -> m b
gom ([a] -> b
f ([a] -> b) -> ([a] -> [a]) -> [a] -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
:)) (t
m t -> t -> t
forall a. Num a => a -> a -> a
- t
1)
        else ([a] -> b) -> Int -> m b
forall {t} {b}. (Ord t, Num t) => ([a] -> b) -> t -> m b
god [a] -> b
f (if Int
m' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 then Int
n' else Int
n' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
m')
    god :: ([a] -> c) -> t -> m c
god [a] -> c
f !t
d =
      if t
d t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
0
        then do
          Maybe a
r <- m a -> m (Maybe a)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
C.optional m a
p
          case Maybe a
r of
            Maybe a
Nothing -> c -> m c
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([a] -> c
f [])
            Just a
x -> ([a] -> c) -> t -> m c
god ([a] -> c
f ([a] -> c) -> ([a] -> [a]) -> [a] -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
:)) (t
d t -> t -> t
forall a. Num a => a -> a -> a
- t
1)
        else c -> m c
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([a] -> c
f [])
{-# INLINE count' #-}
endBy :: MonadPlus m => m a -> m sep -> m [a]
endBy :: forall (m :: * -> *) a sep. MonadPlus m => m a -> m sep -> m [a]
endBy m a
p m sep
sep = m a -> m [a]
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many (m a
p m a -> (a -> m a) -> m a
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
x -> a
x a -> m sep -> m a
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ m sep
sep)
{-# INLINE endBy #-}
endBy1 :: MonadPlus m => m a -> m sep -> m [a]
endBy1 :: forall (m :: * -> *) a sep. MonadPlus m => m a -> m sep -> m [a]
endBy1 m a
p m sep
sep = m a -> m [a]
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
some (m a
p m a -> (a -> m a) -> m a
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
x -> a
x a -> m sep -> m a
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ m sep
sep)
{-# INLINE endBy1 #-}
many :: MonadPlus m => m a -> m [a]
many :: forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many m a
p = ([a] -> [a]) -> m [a]
forall {c}. ([a] -> c) -> m c
go [a] -> [a]
forall a. a -> a
id
  where
    go :: ([a] -> c) -> m c
go [a] -> c
f = do
      Maybe a
r <- m a -> m (Maybe a)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
C.optional m a
p
      case Maybe a
r of
        Maybe a
Nothing -> c -> m c
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([a] -> c
f [])
        Just a
x -> ([a] -> c) -> m c
go ([a] -> c
f ([a] -> c) -> ([a] -> [a]) -> [a] -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
:))
{-# INLINE many #-}
manyTill :: MonadPlus m => m a -> m end -> m [a]
manyTill :: forall (m :: * -> *) a sep. MonadPlus m => m a -> m sep -> m [a]
manyTill m a
p m end
end = ([a], end) -> [a]
forall a b. (a, b) -> a
fst (([a], end) -> [a]) -> m ([a], end) -> m [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a -> m end -> m ([a], end)
forall (m :: * -> *) a end.
MonadPlus m =>
m a -> m end -> m ([a], end)
manyTill_ m a
p m end
end
{-# INLINE manyTill #-}
manyTill_ :: MonadPlus m => m a -> m end -> m ([a], end)
manyTill_ :: forall (m :: * -> *) a end.
MonadPlus m =>
m a -> m end -> m ([a], end)
manyTill_ m a
p m end
end = ([a] -> [a]) -> m ([a], end)
forall {c}. ([a] -> c) -> m (c, end)
go [a] -> [a]
forall a. a -> a
id
  where
    go :: ([a] -> c) -> m (c, end)
go [a] -> c
f = do
      Maybe end
done <- m end -> m (Maybe end)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
C.optional m end
end
      case Maybe end
done of
        Just end
done' -> (c, end) -> m (c, end)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([a] -> c
f [], end
done')
        Maybe end
Nothing -> do
          a
x <- m a
p
          ([a] -> c) -> m (c, end)
go ([a] -> c
f ([a] -> c) -> ([a] -> [a]) -> [a] -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
:))
{-# INLINE manyTill_ #-}
some :: MonadPlus m => m a -> m [a]
some :: forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
some m a
p = (a -> [a] -> [a]) -> m a -> m [a] -> m [a]
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (:) m a
p (m a -> m [a]
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many m a
p)
{-# INLINE some #-}
someTill :: MonadPlus m => m a -> m end -> m [a]
someTill :: forall (m :: * -> *) a sep. MonadPlus m => m a -> m sep -> m [a]
someTill m a
p m end
end = (a -> [a] -> [a]) -> m a -> m [a] -> m [a]
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (:) m a
p (m a -> m end -> m [a]
forall (m :: * -> *) a sep. MonadPlus m => m a -> m sep -> m [a]
manyTill m a
p m end
end)
{-# INLINE someTill #-}
someTill_ :: MonadPlus m => m a -> m end -> m ([a], end)
someTill_ :: forall (m :: * -> *) a end.
MonadPlus m =>
m a -> m end -> m ([a], end)
someTill_ m a
p m end
end = (a -> ([a], end) -> ([a], end))
-> m a -> m ([a], end) -> m ([a], end)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (\a
x ([a]
xs, end
y) -> (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
xs, end
y)) m a
p (m a -> m end -> m ([a], end)
forall (m :: * -> *) a end.
MonadPlus m =>
m a -> m end -> m ([a], end)
manyTill_ m a
p m end
end)
{-# INLINE someTill_ #-}
sepBy :: MonadPlus m => m a -> m sep -> m [a]
sepBy :: forall (m :: * -> *) a sep. MonadPlus m => m a -> m sep -> m [a]
sepBy m a
p m sep
sep = do
  Maybe a
r <- m a -> m (Maybe a)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
C.optional m a
p
  case Maybe a
r of
    Maybe a
Nothing -> [a] -> m [a]
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return []
    Just a
x -> (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
:) ([a] -> [a]) -> m [a] -> m [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a -> m [a]
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many (m sep
sep m sep -> m a -> m a
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> m a
p)
{-# INLINE sepBy #-}
sepBy1 :: MonadPlus m => m a -> m sep -> m [a]
sepBy1 :: forall (m :: * -> *) a sep. MonadPlus m => m a -> m sep -> m [a]
sepBy1 m a
p m sep
sep = do
  a
x <- m a
p
  (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
:) ([a] -> [a]) -> m [a] -> m [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a -> m [a]
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many (m sep
sep m sep -> m a -> m a
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> m a
p)
{-# INLINE sepBy1 #-}
sepEndBy :: MonadPlus m => m a -> m sep -> m [a]
sepEndBy :: forall (m :: * -> *) a sep. MonadPlus m => m a -> m sep -> m [a]
sepEndBy m a
p m sep
sep = ([a] -> [a]) -> m [a]
forall {c}. ([a] -> c) -> m c
go [a] -> [a]
forall a. a -> a
id
  where
    go :: ([a] -> c) -> m c
go [a] -> c
f = do
      Maybe a
r <- m a -> m (Maybe a)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
C.optional m a
p
      case Maybe a
r of
        Maybe a
Nothing -> c -> m c
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([a] -> c
f [])
        Just a
x -> do
          Bool
more <- Bool -> m Bool -> m Bool
forall (m :: * -> *) a. Alternative m => a -> m a -> m a
C.option Bool
False (Bool
True Bool -> m sep -> m Bool
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ m sep
sep)
          if Bool
more
            then ([a] -> c) -> m c
go ([a] -> c
f ([a] -> c) -> ([a] -> [a]) -> [a] -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
:))
            else c -> m c
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([a] -> c
f [a
x])
{-# INLINE sepEndBy #-}
sepEndBy1 :: MonadPlus m => m a -> m sep -> m [a]
sepEndBy1 :: forall (m :: * -> *) a sep. MonadPlus m => m a -> m sep -> m [a]
sepEndBy1 m a
p m sep
sep = do
  a
x <- m a
p
  Bool
more <- Bool -> m Bool -> m Bool
forall (m :: * -> *) a. Alternative m => a -> m a -> m a
C.option Bool
False (Bool
True Bool -> m sep -> m Bool
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ m sep
sep)
  if Bool
more
    then (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
:) ([a] -> [a]) -> m [a] -> m [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a -> m sep -> m [a]
forall (m :: * -> *) a sep. MonadPlus m => m a -> m sep -> m [a]
sepEndBy m a
p m sep
sep
    else [a] -> m [a]
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return [a
x]
{-# INLINE sepEndBy1 #-}
skipMany :: MonadPlus m => m a -> m ()
skipMany :: forall (m :: * -> *) a. MonadPlus m => m a -> m ()
skipMany m a
p = m ()
go
  where
    go :: m ()
go = do
      Bool
more <- Bool -> m Bool -> m Bool
forall (m :: * -> *) a. Alternative m => a -> m a -> m a
C.option Bool
False (Bool
True Bool -> m a -> m Bool
forall a b. a -> m b -> m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ m a
p)
      Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
more m ()
go
{-# INLINE skipMany #-}
skipSome :: MonadPlus m => m a -> m ()
skipSome :: forall (m :: * -> *) a. MonadPlus m => m a -> m ()
skipSome m a
p = m a
p m a -> m () -> m ()
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> m a -> m ()
forall (m :: * -> *) a. MonadPlus m => m a -> m ()
skipMany m a
p
{-# INLINE skipSome #-}
skipCount :: Monad m => Int -> m a -> m ()
skipCount :: forall (m :: * -> *) a. Monad m => Int -> m a -> m ()
skipCount Int
n' m a
p = Int -> m ()
forall {t}. (Ord t, Num t) => t -> m ()
go Int
n'
  where
    go :: t -> m ()
go !t
n =
      Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (t
n t -> t -> Bool
forall a. Ord a => a -> a -> Bool
<= t
0) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
        m a
p m a -> m () -> m ()
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> t -> m ()
go (t
n t -> t -> t
forall a. Num a => a -> a -> a
- t
1)
{-# INLINE skipCount #-}
skipManyTill :: MonadPlus m => m a -> m end -> m end
skipManyTill :: forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m end
skipManyTill m a
p m end
end = m end
go
  where
    go :: m end
go = do
      Maybe end
r <- m end -> m (Maybe end)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
C.optional m end
end
      case Maybe end
r of
        Maybe end
Nothing -> m a
p m a -> m end -> m end
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> m end
go
        Just end
x -> end -> m end
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return end
x
{-# INLINE skipManyTill #-}
skipSomeTill :: MonadPlus m => m a -> m end -> m end
skipSomeTill :: forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m end
skipSomeTill m a
p m end
end = m a
p m a -> m end -> m end
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> m a -> m end -> m end
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m end
skipManyTill m a
p m end
end
{-# INLINE skipSomeTill #-}