-- | Provides the 'AMonoid' typeclass.
--
-- @since 0.1
module Numeric.Algebra.Additive.AMonoid
  ( AMonoid (..),
  )
where

import Data.Complex (Complex)
import Data.Int (Int16, Int32, Int64, Int8)
import Data.Kind (Constraint, Type)
import Data.Ratio (Ratio)
import Data.Word (Word16, Word32, Word64, Word8)
import GHC.Natural (Natural)
import Numeric.Algebra.Additive.ASemigroup (ASemigroup)

-- | Defines a monoid over an additive semigroup.
--
-- @since 0.1
type AMonoid :: Type -> Constraint
class (ASemigroup m) => AMonoid m where
  -- | Should satisfy:
  --
  -- @
  -- -- identity
  -- x .+. zero = x = zero .+. x
  -- @since 0.1
  zero :: m

-- | @since 0.1
instance AMonoid Double where
  zero :: Double
zero = Double
0
  {-# INLINE zero #-}

-- | @since 0.1
instance AMonoid Float where
  zero :: Float
zero = Float
0
  {-# INLINE zero #-}

-- | @since 0.1
instance AMonoid Int where
  zero :: Int
zero = Int
0
  {-# INLINE zero #-}

-- | @since 0.1
instance AMonoid Int8 where
  zero :: Int8
zero = Int8
0
  {-# INLINE zero #-}

-- | @since 0.1
instance AMonoid Int16 where
  zero :: Int16
zero = Int16
0
  {-# INLINE zero #-}

-- | @since 0.1
instance AMonoid Int32 where
  zero :: Int32
zero = Int32
0
  {-# INLINE zero #-}

-- | @since 0.1
instance AMonoid Int64 where
  zero :: Int64
zero = Int64
0
  {-# INLINE zero #-}

-- | @since 0.1
instance AMonoid Integer where
  zero :: Integer
zero = Integer
0
  {-# INLINE zero #-}

-- | @since 0.1
instance AMonoid Word where
  zero :: Word
zero = Word
0
  {-# INLINE zero #-}

-- | @since 0.1
instance AMonoid Word8 where
  zero :: Word8
zero = Word8
0
  {-# INLINE zero #-}

-- | @since 0.1
instance AMonoid Word16 where
  zero :: Word16
zero = Word16
0
  {-# INLINE zero #-}

-- | @since 0.1
instance AMonoid Word32 where
  zero :: Word32
zero = Word32
0
  {-# INLINE zero #-}

-- | @since 0.1
instance AMonoid Word64 where
  zero :: Word64
zero = Word64
0
  {-# INLINE zero #-}

-- | @since 0.1
instance AMonoid Natural where
  zero :: Natural
zero = Natural
0
  {-# INLINE zero #-}

-- | @since 0.1
instance AMonoid (Ratio Integer) where
  zero :: Ratio Integer
zero = Ratio Integer
0
  {-# INLINE zero #-}

-- | @since 0.1
instance AMonoid (Ratio Natural) where
  zero :: Ratio Natural
zero = Ratio Natural
0
  {-# INLINE zero #-}

-- | @since 0.1
instance (RealFloat a) => AMonoid (Complex a) where
  zero :: Complex a
zero = Complex a
0
  {-# INLINE zero #-}

-- | @since 0.1
instance (AMonoid a) => AMonoid (a, a) where
  zero :: (a, a)
zero = (a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero)
  {-# INLINE zero #-}

-- | @since 0.1
instance (AMonoid a) => AMonoid (a, a, a) where
  zero :: (a, a, a)
zero = (a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero)
  {-# INLINE zero #-}

-- | @since 0.1
instance (AMonoid a) => AMonoid (a, a, a, a) where
  zero :: (a, a, a, a)
zero = (a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero)
  {-# INLINE zero #-}

-- | @since 0.1
instance (AMonoid a) => AMonoid (a, a, a, a, a) where
  zero :: (a, a, a, a, a)
zero = (a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero)
  {-# INLINE zero #-}

-- | @since 0.1
instance (AMonoid a) => AMonoid (a, a, a, a, a, a) where
  zero :: (a, a, a, a, a, a)
zero = (a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero)
  {-# INLINE zero #-}

-- | @since 0.1
instance (AMonoid a) => AMonoid (a, a, a, a, a, a, a) where
  zero :: (a, a, a, a, a, a, a)
zero = (a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero)
  {-# INLINE zero #-}

-- | @since 0.1
instance (AMonoid a) => AMonoid (a, a, a, a, a, a, a, a) where
  zero :: (a, a, a, a, a, a, a, a)
zero = (a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero)
  {-# INLINE zero #-}

-- | @since 0.1
instance (AMonoid a) => AMonoid (a, a, a, a, a, a, a, a, a) where
  zero :: (a, a, a, a, a, a, a, a, a)
zero = (a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero, a
forall m. AMonoid m => m
zero)
  {-# INLINE zero #-}