module Text.Parcom.Combinators
( choice, namedChoice
, before, between
, many, many1, manySepBy
, times
, skip
, possibly, optional, option
)
where
import Text.Parcom.Core
import Text.Parcom.Internal
import Control.Monad (liftM)
import Data.Maybe (fromMaybe)
choice :: (Monad m, Stream s t) => [ParcomT s t m a] -> ParcomT s t m a
choice xs = foldl (<|>) empty xs <?> "I tried to make a choice, but couldn't"
namedChoice :: (Monad m, Stream s t) => [(String, ParcomT s t m a)] -> ParcomT s t m a
namedChoice xs = choice (map snd xs) <?> (formatOptionList . map fst) xs
before :: (Monad m, Stream s t) => ParcomT s t m a -> ParcomT s t m b -> ParcomT s t m a
before p q = do { v <- p; q; return v }
between :: (Monad m, Stream s t) => ParcomT s t m a -> ParcomT s t m l -> ParcomT s t m r -> ParcomT s t m a
between p l r = do { l; v <- p; r; return v }
many :: (Monad m, Stream s t) => ParcomT s t m a -> ParcomT s t m [a]
many p =
handle p f m
where
f e = return []
m x = do
xs <- many p
return (x:xs)
many1 :: (Monad m, Stream s t) => ParcomT s t m a -> ParcomT s t m [a]
many1 p = do
xs <- many p
if null xs
then fail "Expected at least one item"
else return xs
manySepBy :: (Monad m, Stream s t) => ParcomT s t m a -> ParcomT s t m b -> ParcomT s t m [a]
manySepBy p s = go
where
go = do
handle p f m
where
f e = return []
m x = handle s
(\e -> return [x])
(\_ -> go >>= \xs -> return (x:xs))
times :: (Monad m, Stream s t) => Int -> ParcomT s t m a -> ParcomT s t m [a]
times 0 p = return []
times n p = do
x <- p
xs <- times (n 1) p
return (x:xs)
skip :: Monad m => ParcomT s t m a -> ParcomT s t m ()
skip p = p >> return ()
possibly :: Monad m => ParcomT s t m a -> ParcomT s t m (Maybe a)
possibly p = Just `liftM` p <|> return Nothing
optional :: Monad m => a -> ParcomT s t m a -> ParcomT s t m a
optional d p = fromMaybe d `liftM` possibly p
option :: Monad m => ParcomT s t m a -> ParcomT s t m ()
option p = skip $ optional undefined p