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 ()
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)