-- | Provides the 'ASemigroup' typeclass.
--
-- @since 0.1
module Numeric.Algebra.Additive.ASemigroup
  ( ASemigroup (..),
  )
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)

-- | Defines an additive semigroup.
--
-- @since 0.1
type ASemigroup :: Type -> Constraint
class ASemigroup s where
  -- | @since 0.1
  (.+.) :: s -> s -> s

infixl 6 .+.

-- | @since 0.1
instance ASemigroup Double where
  .+. :: Double -> Double -> Double
(.+.) = Double -> Double -> Double
forall a. Num a => a -> a -> a
(+)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance ASemigroup Float where
  .+. :: Float -> Float -> Float
(.+.) = Float -> Float -> Float
forall a. Num a => a -> a -> a
(+)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance ASemigroup Int where
  .+. :: Int -> Int -> Int
(.+.) = Int -> Int -> Int
forall a. Num a => a -> a -> a
(+)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance ASemigroup Int8 where
  .+. :: Int8 -> Int8 -> Int8
(.+.) = Int8 -> Int8 -> Int8
forall a. Num a => a -> a -> a
(+)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance ASemigroup Int16 where
  .+. :: Int16 -> Int16 -> Int16
(.+.) = Int16 -> Int16 -> Int16
forall a. Num a => a -> a -> a
(+)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance ASemigroup Int32 where
  .+. :: Int32 -> Int32 -> Int32
(.+.) = Int32 -> Int32 -> Int32
forall a. Num a => a -> a -> a
(+)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance ASemigroup Int64 where
  .+. :: Int64 -> Int64 -> Int64
(.+.) = Int64 -> Int64 -> Int64
forall a. Num a => a -> a -> a
(+)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance ASemigroup Integer where
  .+. :: Integer -> Integer -> Integer
(.+.) = Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(+)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance ASemigroup Word where
  .+. :: Word -> Word -> Word
(.+.) = Word -> Word -> Word
forall a. Num a => a -> a -> a
(+)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance ASemigroup Word8 where
  .+. :: Word8 -> Word8 -> Word8
(.+.) = Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
(+)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance ASemigroup Word16 where
  .+. :: Word16 -> Word16 -> Word16
(.+.) = Word16 -> Word16 -> Word16
forall a. Num a => a -> a -> a
(+)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance ASemigroup Word32 where
  .+. :: Word32 -> Word32 -> Word32
(.+.) = Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
(+)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance ASemigroup Word64 where
  .+. :: Word64 -> Word64 -> Word64
(.+.) = Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
(+)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance ASemigroup Natural where
  .+. :: Natural -> Natural -> Natural
(.+.) = Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
(+)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance ASemigroup (Ratio Integer) where
  .+. :: Ratio Integer -> Ratio Integer -> Ratio Integer
(.+.) = Ratio Integer -> Ratio Integer -> Ratio Integer
forall a. Num a => a -> a -> a
(+)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance ASemigroup (Ratio Natural) where
  .+. :: Ratio Natural -> Ratio Natural -> Ratio Natural
(.+.) = Ratio Natural -> Ratio Natural -> Ratio Natural
forall a. Num a => a -> a -> a
(+)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance (RealFloat a) => ASemigroup (Complex a) where
  .+. :: Complex a -> Complex a -> Complex a
(.+.) = Complex a -> Complex a -> Complex a
forall a. Num a => a -> a -> a
(+)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance (ASemigroup a) => ASemigroup (a, a) where
  (a
x1, a
x2) .+. :: (a, a) -> (a, a) -> (a, a)
.+. (a
y1, a
y2) = (a
x1 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y1, a
x2 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y2)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance (ASemigroup a) => ASemigroup (a, a, a) where
  (a
x1, a
x2, a
x3) .+. :: (a, a, a) -> (a, a, a) -> (a, a, a)
.+. (a
y1, a
y2, a
y3) = (a
x1 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y1, a
x2 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y2, a
x3 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y3)
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance (ASemigroup a) => ASemigroup (a, a, a, a) where
  (a
x1, a
x2, a
x3, a
x4) .+. :: (a, a, a, a) -> (a, a, a, a) -> (a, a, a, a)
.+. (a
y1, a
y2, a
y3, a
y4) =
    ( a
x1 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y1,
      a
x2 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y2,
      a
x3 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y3,
      a
x4 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y4
    )
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance (ASemigroup a) => ASemigroup (a, a, a, a, a) where
  (a
x1, a
x2, a
x3, a
x4, a
x5) .+. :: (a, a, a, a, a) -> (a, a, a, a, a) -> (a, a, a, a, a)
.+. (a
y1, a
y2, a
y3, a
y4, a
y5) =
    ( a
x1 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y1,
      a
x2 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y2,
      a
x3 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y3,
      a
x4 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y4,
      a
x5 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y5
    )
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance (ASemigroup a) => ASemigroup (a, a, a, a, a, a) where
  (a
x1, a
x2, a
x3, a
x4, a
x5, a
x6) .+. :: (a, a, a, a, a, a) -> (a, a, a, a, a, a) -> (a, a, a, a, a, a)
.+. (a
y1, a
y2, a
y3, a
y4, a
y5, a
y6) =
    ( a
x1 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y1,
      a
x2 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y2,
      a
x3 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y3,
      a
x4 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y4,
      a
x5 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y5,
      a
x6 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y6
    )
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance (ASemigroup a) => ASemigroup (a, a, a, a, a, a, a) where
  (a
x1, a
x2, a
x3, a
x4, a
x5, a
x6, a
x7) .+. :: (a, a, a, a, a, a, a)
-> (a, a, a, a, a, a, a) -> (a, a, a, a, a, a, a)
.+. (a
y1, a
y2, a
y3, a
y4, a
y5, a
y6, a
y7) =
    ( a
x1 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y1,
      a
x2 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y2,
      a
x3 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y3,
      a
x4 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y4,
      a
x5 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y5,
      a
x6 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y6,
      a
x7 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y7
    )
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance (ASemigroup a) => ASemigroup (a, a, a, a, a, a, a, a) where
  (a
x1, a
x2, a
x3, a
x4, a
x5, a
x6, a
x7, a
x8) .+. :: (a, a, a, a, a, a, a, a)
-> (a, a, a, a, a, a, a, a) -> (a, a, a, a, a, a, a, a)
.+. (a
y1, a
y2, a
y3, a
y4, a
y5, a
y6, a
y7, a
y8) =
    ( a
x1 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y1,
      a
x2 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y2,
      a
x3 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y3,
      a
x4 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y4,
      a
x5 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y5,
      a
x6 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y6,
      a
x7 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y7,
      a
x8 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y8
    )
  {-# INLINE (.+.) #-}

-- | @since 0.1
instance (ASemigroup a) => ASemigroup (a, a, a, a, a, a, a, a, a) where
  (a
x1, a
x2, a
x3, a
x4, a
x5, a
x6, a
x7, a
x8, a
x9) .+. :: (a, a, a, a, a, a, a, a, a)
-> (a, a, a, a, a, a, a, a, a) -> (a, a, a, a, a, a, a, a, a)
.+. (a
y1, a
y2, a
y3, a
y4, a
y5, a
y6, a
y7, a
y8, a
y9) =
    ( a
x1 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y1,
      a
x2 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y2,
      a
x3 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y3,
      a
x4 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y4,
      a
x5 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y5,
      a
x6 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y6,
      a
x7 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y7,
      a
x8 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y8,
      a
x9 a -> a -> a
forall s. ASemigroup s => s -> s -> s
.+. a
y9
    )
  {-# INLINE (.+.) #-}