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

import Integer.Integer (Integer)
import Integer.Natural (Natural)
import Integer.Natural qualified as Natural
import Integer.Positive (Positive)
import Integer.Positive qualified as Positive
import Integer.Signed (Signed)
import Integer.Signed qualified as Signed
import Prelude qualified 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