module Integer.Subtraction
  (
    Subtraction (subtractInteger, subtractSigned),
    Subtraction' (subtract),
  )
  where

import Integer.Integer (Integer)
import Integer.Natural (Natural)
import Integer.Positive (Positive)
import Integer.Signed (Signed)

import qualified Integer.Natural as Natural
import qualified Integer.Positive as Positive
import qualified Integer.Signed as Signed
import qualified Prelude as Num (Num (..))

-- | Domain of a subtraction operation
class Subtraction a where
    subtractInteger :: a -> a -> Integer
    subtractInteger a
a a
b = Signed -> Integer
Signed.toInteger (forall a. Subtraction a => a -> a -> Signed
subtractSigned a
a a
b)

    subtractSigned  :: a -> a -> Signed
    subtractSigned a
a a
b = Integer -> Signed
Signed.fromInteger (forall a. Subtraction a => a -> a -> Integer
subtractInteger a
a a
b)

instance Subtraction Integer where
    subtractInteger :: Integer -> Integer -> Integer
subtractInteger = forall a. Num a => a -> a -> a
(Num.-)

instance Subtraction Signed where
    subtractInteger :: Signed -> Signed -> Integer
subtractInteger Signed
a Signed
b = forall a. Num a => a -> a -> a
(Num.-) (Signed -> Integer
Signed.toInteger Signed
a) (Signed -> Integer
Signed.toInteger Signed
b)
    subtractSigned :: Signed -> Signed -> Signed
subtractSigned = forall a. Num a => a -> a -> a
(Num.-)

instance Subtraction Natural where
    subtractSigned :: Natural -> Natural -> Signed
subtractSigned = Natural -> Natural -> Signed
Natural.subtract

instance Subtraction Positive where
    subtractSigned :: Positive -> Positive -> Signed
subtractSigned = Positive -> Positive -> Signed
Positive.subtract

-- | Codomain of a subtraction operation
class Subtraction' b where
    subtract :: Subtraction a => a -> a -> b

instance Subtraction' Integer where
    subtract :: forall a. Subtraction a => a -> a -> Integer
subtract = forall a. Subtraction a => a -> a -> Integer
subtractInteger

instance Subtraction' Signed where
    subtract :: forall a. Subtraction a => a -> a -> Signed
subtract = forall a. Subtraction a => a -> a -> Signed
subtractSigned