-- | Some semigroup instances used in several places

module Agda.Utils.Semigroup where

import Control.Applicative (liftA2)

import Control.Monad.Except (ExceptT)
import Control.Monad.Reader (ReaderT)
import Control.Monad.State  (StateT)
import Control.Monad.Writer (WriterT)
import Control.Monad.Trans.Maybe (MaybeT)

instance (Monad m, Semigroup doc)       => Semigroup (ExceptT e m doc) where
  {-# INLINE (<>) #-}
  <> :: ExceptT e m doc -> ExceptT e m doc -> ExceptT e m doc
(<>) = (doc -> doc -> doc)
-> ExceptT e m doc -> ExceptT e m doc -> ExceptT e m doc
forall a b c.
(a -> b -> c) -> ExceptT e m a -> ExceptT e m b -> ExceptT e m c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 doc -> doc -> doc
forall a. Semigroup a => a -> a -> a
(<>)

instance (Monad m, Semigroup doc)       => Semigroup (MaybeT m doc) where
  {-# INLINE (<>) #-}
  <> :: MaybeT m doc -> MaybeT m doc -> MaybeT m doc
(<>) = (doc -> doc -> doc) -> MaybeT m doc -> MaybeT m doc -> MaybeT m doc
forall a b c.
(a -> b -> c) -> MaybeT m a -> MaybeT m b -> MaybeT m c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 doc -> doc -> doc
forall a. Semigroup a => a -> a -> a
(<>)

instance (Applicative m, Semigroup doc) => Semigroup (ReaderT s m doc) where
  {-# INLINE (<>) #-}
  <> :: ReaderT s m doc -> ReaderT s m doc -> ReaderT s m doc
(<>) = (doc -> doc -> doc)
-> ReaderT s m doc -> ReaderT s m doc -> ReaderT s m doc
forall a b c.
(a -> b -> c) -> ReaderT s m a -> ReaderT s m b -> ReaderT s m c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 doc -> doc -> doc
forall a. Semigroup a => a -> a -> a
(<>)

instance (Monad m, Semigroup doc)       => Semigroup (StateT s m doc)  where
  {-# INLINE (<>) #-}
  <> :: StateT s m doc -> StateT s m doc -> StateT s m doc
(<>) = (doc -> doc -> doc)
-> StateT s m doc -> StateT s m doc -> StateT s m doc
forall a b c.
(a -> b -> c) -> StateT s m a -> StateT s m b -> StateT s m c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 doc -> doc -> doc
forall a. Semigroup a => a -> a -> a
(<>)

instance (Monad m, Semigroup doc, Monoid w) => Semigroup (WriterT w m doc)  where
  {-# INLINE (<>) #-}
  <> :: WriterT w m doc -> WriterT w m doc -> WriterT w m doc
(<>) = (doc -> doc -> doc)
-> WriterT w m doc -> WriterT w m doc -> WriterT w m doc
forall a b c.
(a -> b -> c) -> WriterT w m a -> WriterT w m b -> WriterT w m c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 doc -> doc -> doc
forall a. Semigroup a => a -> a -> a
(<>)