{-# 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 :: 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 (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' :: 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 (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] -> a) -> t -> m a
god [a] -> a
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 -> a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([a] -> a
f [])
Just a
x -> ([a] -> a) -> t -> m a
god ([a] -> a
f ([a] -> a) -> ([a] -> [a]) -> [a] -> a
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 a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([a] -> a
f [])
{-# INLINE count' #-}
endBy :: MonadPlus m => m a -> m sep -> m [a]
endBy :: 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 (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
x -> a
x a -> m sep -> 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 :: 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 (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
x -> a
x a -> m sep -> 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 :: 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 (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 :: m a -> m end -> 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_ :: 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 (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 :: 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 :: m a -> m end -> 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 end. MonadPlus m => m a -> m end -> m [a]
manyTill m a
p m end
end)
{-# INLINE someTill #-}
someTill_ :: MonadPlus m => m a -> m end -> m ([a], end)
someTill_ :: 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 :: 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 (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 (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 :: 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 (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 :: m a -> m sep -> m [a]
sepEndBy m a
p m sep
sep = ([a] -> [a]) -> m [a]
forall a. ([a] -> a) -> m a
go [a] -> [a]
forall a. a -> a
id
where
go :: ([a] -> a) -> m a
go [a] -> a
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 -> a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([a] -> a
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 (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ m sep
sep)
if Bool
more
then ([a] -> a) -> m a
go ([a] -> a
f ([a] -> a) -> ([a] -> [a]) -> [a] -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
:))
else a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return ([a] -> a
f [a
x])
{-# INLINE sepEndBy #-}
sepEndBy1 :: MonadPlus m => m a -> m sep -> m [a]
sepEndBy1 :: 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 (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 end. MonadPlus m => m a -> m end -> m [a]
sepEndBy m a
p m sep
sep
else [a] -> m [a]
forall (m :: * -> *) a. Monad m => a -> m a
return [a
x]
{-# INLINE sepEndBy1 #-}
skipMany :: MonadPlus m => m a -> m ()
skipMany :: 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 (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 :: m a -> m ()
skipSome m a
p = m a
p m a -> m () -> m ()
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 :: 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 (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 :: 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 (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> m end
go
Just end
x -> end -> m end
forall (m :: * -> *) a. Monad m => a -> m a
return end
x
{-# INLINE skipManyTill #-}
skipSomeTill :: MonadPlus m => m a -> m end -> m end
skipSomeTill :: m a -> m end -> m end
skipSomeTill m a
p m end
end = m a
p m a -> m end -> m end
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 #-}