-- | Provides typeclasses for division.
--
-- @since 0.1
module Numeric.Algebra.Multiplicative.MGroup
  ( MGroup (..),
  )
where

import Data.Complex (Complex)
import Data.Int (Int16, Int32, Int64, Int8)
import Data.Kind (Constraint, Type)
import Data.Word (Word16, Word32, Word64, Word8)
import GHC.Natural (Natural)
import GHC.Real (Ratio)
import Numeric.Algebra.Multiplicative.MMonoid (MMonoid)
import Numeric.Algebra.Multiplicative.MSemigroup (MSemigroup ((.*.)))

-- | Defines a multiplicative group.
--
-- @since 0.1
type MGroup :: Type -> Constraint
class (MMonoid g) => MGroup g where
  -- | @since 0.1
  (.%.) :: g -> g -> g

infixl 7 .%.

-- | @since 0.1
instance MGroup Double where
  .%. :: Double -> Double -> Double
(.%.) = Double -> Double -> Double
forall a. Fractional a => a -> a -> a
(/)
  {-# INLINE (.%.) #-}

-- | @since 0.1
instance MGroup Float where
  .%. :: Float -> Float -> Float
(.%.) = Float -> Float -> Float
forall a. Fractional a => a -> a -> a
(/)
  {-# INLINE (.%.) #-}

-- | @since 0.1
instance MGroup Int where
  .%. :: Int -> Int -> Int
(.%.) = Int -> Int -> Int
forall a. Integral a => a -> a -> a
div
  {-# INLINE (.%.) #-}

-- | @since 0.1
instance MGroup Int8 where
  .%. :: Int8 -> Int8 -> Int8
(.%.) = Int8 -> Int8 -> Int8
forall a. Integral a => a -> a -> a
div
  {-# INLINE (.%.) #-}

-- | @since 0.1
instance MGroup Int16 where
  .%. :: Int16 -> Int16 -> Int16
(.%.) = Int16 -> Int16 -> Int16
forall a. Integral a => a -> a -> a
div
  {-# INLINE (.%.) #-}

-- | @since 0.1
instance MGroup Int32 where
  .%. :: Int32 -> Int32 -> Int32
(.%.) = Int32 -> Int32 -> Int32
forall a. Integral a => a -> a -> a
div
  {-# INLINE (.%.) #-}

-- | @since 0.1
instance MGroup Int64 where
  .%. :: Int64 -> Int64 -> Int64
(.%.) = Int64 -> Int64 -> Int64
forall a. Integral a => a -> a -> a
div
  {-# INLINE (.%.) #-}

-- | @since 0.1
instance MGroup Integer where
  .%. :: Integer -> Integer -> Integer
(.%.) = Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
div
  {-# INLINE (.%.) #-}

-- | @since 0.1
instance MGroup Word where
  .%. :: Word -> Word -> Word
(.%.) = Word -> Word -> Word
forall a. Integral a => a -> a -> a
div
  {-# INLINE (.%.) #-}

-- | @since 0.1
instance MGroup Word8 where
  .%. :: Word8 -> Word8 -> Word8
(.%.) = Word8 -> Word8 -> Word8
forall a. Integral a => a -> a -> a
div
  {-# INLINE (.%.) #-}

-- | @since 0.1
instance MGroup Word16 where
  .%. :: Word16 -> Word16 -> Word16
(.%.) = Word16 -> Word16 -> Word16
forall a. Integral a => a -> a -> a
div
  {-# INLINE (.%.) #-}

-- | @since 0.1
instance MGroup Word32 where
  .%. :: Word32 -> Word32 -> Word32
(.%.) = Word32 -> Word32 -> Word32
forall a. Integral a => a -> a -> a
div
  {-# INLINE (.%.) #-}

-- | @since 0.1
instance MGroup Word64 where
  .%. :: Word64 -> Word64 -> Word64
(.%.) = Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
div
  {-# INLINE (.%.) #-}

-- | @since 0.1
instance MGroup Natural where
  .%. :: Natural -> Natural -> Natural
(.%.) = Natural -> Natural -> Natural
forall a. Integral a => a -> a -> a
div
  {-# INLINE (.%.) #-}

-- | @since 0.1
instance MGroup (Ratio Integer) where
  Ratio Integer
x .%. :: Ratio Integer -> Ratio Integer -> Ratio Integer
.%. Ratio Integer
d = Ratio Integer
x Ratio Integer -> Ratio Integer -> Ratio Integer
forall s. MSemigroup s => s -> s -> s
.*. Ratio Integer -> Ratio Integer
forall a. Fractional a => a -> a
recip Ratio Integer
d
  {-# INLINE (.%.) #-}

-- | @since 0.1
instance MGroup (Ratio Natural) where
  Ratio Natural
x .%. :: Ratio Natural -> Ratio Natural -> Ratio Natural
.%. Ratio Natural
d = Ratio Natural
x Ratio Natural -> Ratio Natural -> Ratio Natural
forall s. MSemigroup s => s -> s -> s
.*. Ratio Natural -> Ratio Natural
forall a. Fractional a => a -> a
recip Ratio Natural
d
  {-# INLINE (.%.) #-}

-- | @since 0.1
instance (RealFloat a) => MGroup (Complex a) where
  .%. :: Complex a -> Complex a -> Complex a
(.%.) = Complex a -> Complex a -> Complex a
forall a. Fractional a => a -> a -> a
(/)
  {-# INLINE (.%.) #-}