module Data.Syntax.Printer.Consumer where
import Control.Applicative
import Control.Lens.SemiIso
import Control.Monad
import Data.Monoid
import Data.SemiIsoFunctor
newtype Consumer m a = Consumer { runConsumer :: a -> Either String m }
instance SemiIsoFunctor (Consumer m) where
simap f (Consumer p) = Consumer $ apply f >=> p
instance Monoid m => SemiIsoApply (Consumer m) where
siunit = Consumer $ \_ -> Right mempty
Consumer f /*/ Consumer g = Consumer $ \(a, b) -> (<>) <$> f a <*> g b
instance Monoid m => SemiIsoAlternative (Consumer m) where
siempty = Consumer $ \_ -> Left "siempty"
Consumer f /|/ Consumer g = Consumer $ \a -> f a <|> g a
instance Monoid m => SemiIsoMonad (Consumer m) where
Consumer m //= f = Consumer $ \(a, b) -> (<>) <$> m a <*> runConsumer (f a) b