module Data.Syntax.Combinator where
import Control.Lens
import Control.Lens.SemiIso
import Data.SemiIsoFunctor
optional :: SemiIsoAlternative f => f a -> f (Maybe a)
optional f = _Just /$/ f /|/ sipure _Nothing
opt :: SemiIsoAlternative f => f () -> f ()
opt f = f /|/ sipure id
opt_ :: SemiIsoAlternative f => f () -> f ()
opt_ f = semiIso (const (Left "opt_")) Right /$/ f
/|/ sipure id
manyTill :: SemiIsoAlternative f => f a -> f () -> f [a]
manyTill p end = _Empty /$/ end
/|/ _Cons /$/ p /*/ manyTill p end
sepBy :: SemiIsoAlternative f => f a -> f () -> f [a]
sepBy v s = sepBy1 v s /|/ sipure _Empty
sepBy1 :: SemiIsoAlternative f => f a -> f () -> f [a]
sepBy1 v s = _Cons /$/ v /*/ (s */ sepBy1 v s /|/ sipure _Empty)
choice :: SemiIsoAlternative f => [f a] -> f a
choice = foldr (/|/) (sifail "choice: all alternatives failed")
eitherOf :: SemiIsoAlternative f => f a -> f b -> f (Either a b)
eitherOf a b = _Left /$/ a /|/ _Right /$/ b