-- | Provides the 'MSemiSpace' typeclass.
--
-- @since 0.1
module Numeric.Algebra.Space.MSemiSpace
  ( MSemiSpace (..),
    (*.),
  )
where

import Data.Kind (Constraint, Type)
import Numeric.Algebra.Multiplicative.MSemigroup (MSemigroup ((.*.)))

-- | Defines a "multiplicative semi space" over an 'MSemigroup'. This
-- generalizes the notion of a 'Numeric.Algebra.Space.Semimodule.Semimodule'
-- \(M\) over a 'Numeric.Algebra.Ring.Ring' \(R\) in that we assume no
-- additive structure on the space itself.
--
-- @since 0.1
type MSemiSpace :: Type -> Type -> Constraint
class (MSemigroup r) => MSemiSpace m r | m -> r where
  -- | @since 0.1
  (.*) :: m -> r -> m

infixl 7 .*

-- | @since 0.1
(*.) :: (MSemiSpace m r) => r -> m -> m
*. :: forall m r. MSemiSpace m r => r -> m -> m
(*.) = (m -> r -> m) -> r -> m -> m
forall a b c. (a -> b -> c) -> b -> a -> c
flip m -> r -> m
forall m r. MSemiSpace m r => m -> r -> m
(.*)
{-# INLINE (*.) #-}

infixl 7 *.

-- | @since 0.1
instance (MSemigroup r) => MSemiSpace (r, r) r where
  (r
n1, r
n2) .* :: (r, r) -> r -> (r, r)
.* r
m = (r
n1 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m, r
n2 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m)
  {-# INLINE (.*) #-}

-- | @since 0.1
instance (MSemigroup r) => MSemiSpace (r, r, r) r where
  (r
n1, r
n2, r
n3) .* :: (r, r, r) -> r -> (r, r, r)
.* r
m = (r
n1 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m, r
n2 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m, r
n3 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m)
  {-# INLINE (.*) #-}

-- | @since 0.1
instance (MSemigroup r) => MSemiSpace (r, r, r, r) r where
  (r
n1, r
n2, r
n3, r
n4) .* :: (r, r, r, r) -> r -> (r, r, r, r)
.* r
m = (r
n1 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m, r
n2 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m, r
n3 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m, r
n4 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m)
  {-# INLINE (.*) #-}

-- | @since 0.1
instance (MSemigroup r) => MSemiSpace (r, r, r, r, r) r where
  (r
n1, r
n2, r
n3, r
n4, r
n5) .* :: (r, r, r, r, r) -> r -> (r, r, r, r, r)
.* r
m =
    ( r
n1 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n2 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n3 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n4 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n5 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m
    )
  {-# INLINE (.*) #-}

-- | @since 0.1
instance (MSemigroup r) => MSemiSpace (r, r, r, r, r, r) r where
  (r
n1, r
n2, r
n3, r
n4, r
n5, r
n6) .* :: (r, r, r, r, r, r) -> r -> (r, r, r, r, r, r)
.* r
m =
    ( r
n1 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n2 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n3 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n4 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n5 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n6 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m
    )
  {-# INLINE (.*) #-}

-- | @since 0.1
instance (MSemigroup r) => MSemiSpace (r, r, r, r, r, r, r) r where
  (r
n1, r
n2, r
n3, r
n4, r
n5, r
n6, r
n7) .* :: (r, r, r, r, r, r, r) -> r -> (r, r, r, r, r, r, r)
.* r
m =
    ( r
n1 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n2 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n3 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n4 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n5 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n6 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n7 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m
    )
  {-# INLINE (.*) #-}

-- | @since 0.1
instance (MSemigroup r) => MSemiSpace (r, r, r, r, r, r, r, r) r where
  (r
n1, r
n2, r
n3, r
n4, r
n5, r
n6, r
n7, r
n8) .* :: (r, r, r, r, r, r, r, r) -> r -> (r, r, r, r, r, r, r, r)
.* r
m =
    ( r
n1 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n2 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n3 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n4 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n5 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n6 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n7 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n8 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m
    )
  {-# INLINE (.*) #-}

-- | @since 0.1
instance (MSemigroup r) => MSemiSpace (r, r, r, r, r, r, r, r, r) r where
  (r
n1, r
n2, r
n3, r
n4, r
n5, r
n6, r
n7, r
n8, r
n9) .* :: (r, r, r, r, r, r, r, r, r) -> r -> (r, r, r, r, r, r, r, r, r)
.* r
m =
    ( r
n1 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n2 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n3 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n4 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n5 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n6 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n7 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n8 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m,
      r
n9 r -> r -> r
forall s. MSemigroup s => s -> s -> s
.*. r
m
    )
  {-# INLINE (.*) #-}