packages feed

integer-types-0.1.4.0: library/Integer/AbsoluteDifference.hs

module Integer.AbsoluteDifference where

import Essentials
import Integer.Integer (Integer)
import Integer.Integer qualified as Integer
import Integer.Natural (Natural)
import Integer.Positive (Positive)
import Integer.Positive qualified as Positive
import Integer.Signed (Signed (Minus, NonZero, Plus, Zero))
import Integer.Signed qualified as Signed
import Prelude (fromInteger, (+), (-))
import Prelude qualified as Num (abs)

class AbsoluteDifference a b where
  absoluteDifference :: a -> b -> Natural

--

instance AbsoluteDifference Integer Integer where
  absoluteDifference a b = fromInteger $ Num.abs $ a - b

instance AbsoluteDifference Natural Natural where
  absoluteDifference a b = if a >= b then a - b else b - a

instance AbsoluteDifference Positive Positive where
  absoluteDifference a b =
    absoluteDifference
      (Positive.toNatural a)
      (Positive.toNatural b)

instance AbsoluteDifference Signed Signed where
  absoluteDifference Zero Zero = 0
  absoluteDifference Zero (NonZero _ x) = Positive.toNatural x
  absoluteDifference (NonZero _ x) Zero = Positive.toNatural x
  absoluteDifference (NonZero s1 x1) (NonZero s2 x2) =
    if s1 == s2
      then absoluteDifference x1 x2
      else Positive.toNatural (x1 + x2)

--

instance AbsoluteDifference Positive Natural where
  absoluteDifference p n = absoluteDifference (Positive.toNatural p) n

instance AbsoluteDifference Natural Positive where
  absoluteDifference n p = absoluteDifference p n

--

instance AbsoluteDifference Signed Natural where
  absoluteDifference Zero n = n
  absoluteDifference (Plus a) b = absoluteDifference a b
  absoluteDifference (Minus a) b = Positive.toNatural a + b

instance AbsoluteDifference Natural Signed where
  absoluteDifference n s = absoluteDifference s n

--

instance AbsoluteDifference Integer Natural where
  absoluteDifference i n = absoluteDifference (Integer.toSigned i) n

instance AbsoluteDifference Natural Integer where
  absoluteDifference n i = absoluteDifference i n

--

instance AbsoluteDifference Signed Positive where
  absoluteDifference Zero p = Positive.toNatural p
  absoluteDifference (Plus a) b = absoluteDifference a b
  absoluteDifference (Minus a) b = Positive.toNatural (a + b)

instance AbsoluteDifference Positive Signed where
  absoluteDifference p s = absoluteDifference s p

--

instance AbsoluteDifference Signed Integer where
  absoluteDifference s i = absoluteDifference (Signed.toInteger s) i

instance AbsoluteDifference Integer Signed where
  absoluteDifference i s = absoluteDifference s i

--

instance AbsoluteDifference Positive Integer where
  absoluteDifference p i = absoluteDifference (Positive.toInteger p) i

instance AbsoluteDifference Integer Positive where
  absoluteDifference i p = absoluteDifference p i