module Data.Monoid.Reader where import qualified Data.Monoid.Transformer as MonoidTrans import Data.Monoid (Monoid, mempty, mappend, ) import Data.Semigroup (Semigroup, (<>), ) import Data.Functor (Functor, fmap, ) import Data.Function (const, ($), (.), ) import Prelude () {- | Could also be written as @Monoid.Applicative (Monad.Trans.Reader r) a@. -} newtype T r a = Cons {run :: r -> a} pure :: a -> T r a pure = Cons . const instance Semigroup a => Semigroup (T r a) where Cons x <> Cons y = Cons $ \r -> x r <> y r instance Monoid a => Monoid (T r a) where mempty = MonoidTrans.lift mempty mappend (Cons x) (Cons y) = Cons $ \r -> mappend (x r) (y r) instance MonoidTrans.C (T r) where lift = Cons . const instance Functor (T r) where fmap f (Cons g) = Cons (f . g)