{-# LANGUAGE TypeSynonymInstances, TypeOperators, GeneralizedNewtypeDeriving #-}
{-# OPTIONS_GHC -Wall #-}
module Data.CxMonoid (MonoidDict, CxMonoid(..), biCxMonoid) where
import Data.Monoid (Monoid(..))
import qualified Data.Semigroup as Sem
import Data.Bijection
import Data.Title
type MonoidDict a = (a, a -> a -> a)
newtype CxMonoid a = CxMonoid { unCxMonoid :: MonoidDict a -> a }
biCxMonoid :: (MonoidDict a -> a) :<->: CxMonoid a
biCxMonoid = Bi CxMonoid unCxMonoid
instance Sem.Semigroup (CxMonoid a) where
CxMonoid f <> CxMonoid g =
CxMonoid (\ md@(_,op) -> f md `op` g md)
instance Monoid (CxMonoid a) where
mempty = CxMonoid (\ (e,_) -> e)
mappend = (Sem.<>)
instance Title a => Title (CxMonoid a) where
title str = inBi biCxMonoid $ title str