module Precursor.Algebra.Monoid
(
Monoid
, mempty
, mappend
, Dual(..)
, Endo(..)
, Sum(..)
, Product(..)
, Option(..)
, option
) where
import Precursor.Control.Applicative
import Data.Coerce
import Data.Semigroup hiding (Product (..), Sum (..))
import Precursor.Control.Functor
import GHC.Generics
import Precursor.Control.Monad
import Precursor.Numeric.Num
import Prelude (Bounded, Eq, Ord)
import Precursor.Algebra.Semiring
import Precursor.Text.Show
newtype Sum a = Sum { getSum :: a }
deriving (Eq, Ord, Bounded, Generic, Generic1, Num)
instance TextShow a => TextShow (Sum a) where showbPrec = gShowPrec
instance Semiring a => Semigroup (Sum a) where
(<>) =
(coerce :: (a -> a -> a) -> (Sum a -> Sum a -> Sum a)) (+)
instance Semiring a => Monoid (Sum a) where
mappend = (<>)
mempty = Sum zero
instance Functor Sum where
fmap = coerce
instance Applicative Sum where
pure = Sum
(<*>) = coerce
instance Monad Sum where
m >>= k = k (getSum m)
newtype Product a = Product { getProduct :: a }
deriving (Eq, Ord, Bounded, Generic, Generic1, Num)
instance TextShow a => TextShow (Product a) where showbPrec = gShowPrec
instance Semiring a => Semigroup (Product a) where
(<>) =
(coerce :: (a -> a -> a) -> (Product a -> Product a -> Product a)) (*)
instance Semiring a => Monoid (Product a) where
mempty = Product one
mappend = (<>)
instance Functor Product where
fmap = coerce
instance Applicative Product where
pure = Product
(<*>) = coerce
instance Monad Product where
m >>= k = k (getProduct m)