{-# LANGUAGE CPP, UndecidableInstances #-}
module Basement.Numerical.Subtractive
    ( Subtractive(..)
    ) where

import           Basement.Compat.Base
import           Basement.Compat.C.Types
import           Basement.Compat.Natural
import           Basement.IntegralConv
import           Basement.Bounded
import           Basement.Nat
import           Basement.Types.Word128 (Word128)
import           Basement.Types.Word256 (Word256)
import qualified Basement.Types.Word128 as Word128
import qualified Basement.Types.Word256 as Word256
import qualified Prelude

-- | Represent class of things that can be subtracted.
--
--
-- Note that the result is not necessary of the same type
-- as the operand depending on the actual type.
--
-- For example:
--
-- > (-) :: Int -> Int -> Int
-- > (-) :: DateTime -> DateTime -> Seconds
-- > (-) :: Ptr a -> Ptr a -> PtrDiff
-- > (-) :: Natural -> Natural -> Maybe Natural
class Subtractive a where
    type Difference a
    (-) :: a -> a -> Difference a

infixl 6 -

instance Subtractive Integer where
    type Difference Integer = Integer
    (-) = Integer -> Integer -> Integer
Integer -> Integer -> Difference Integer
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Int where
    type Difference Int = Int
    (-) = Int -> Int -> Int
Int -> Int -> Difference Int
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Int8 where
    type Difference Int8 = Int8
    (-) = Int8 -> Int8 -> Int8
Int8 -> Int8 -> Difference Int8
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Int16 where
    type Difference Int16 = Int16
    (-) = Int16 -> Int16 -> Int16
Int16 -> Int16 -> Difference Int16
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Int32 where
    type Difference Int32 = Int32
    (-) = Int32 -> Int32 -> Int32
Int32 -> Int32 -> Difference Int32
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Int64 where
    type Difference Int64 = Int64
    (-) = Int64 -> Int64 -> Int64
Int64 -> Int64 -> Difference Int64
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Natural where
    type Difference Natural = Maybe Natural
    (-) Natural
a Natural
b
        | Natural
b Natural -> Natural -> Bool
forall a. Ord a => a -> a -> Bool
> Natural
a     = Maybe Natural
Difference Natural
forall a. Maybe a
Nothing
        | Bool
otherwise = Natural -> Maybe Natural
forall a. a -> Maybe a
Just (Natural
a Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
Prelude.- Natural
b)
instance Subtractive Word where
    type Difference Word = Word
    (-) = Word -> Word -> Word
Word -> Word -> Difference Word
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Word8 where
    type Difference Word8 = Word8
    (-) = Word8 -> Word8 -> Word8
Word8 -> Word8 -> Difference Word8
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Word16 where
    type Difference Word16 = Word16
    (-) = Word16 -> Word16 -> Word16
Word16 -> Word16 -> Difference Word16
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Word32 where
    type Difference Word32 = Word32
    (-) = Word32 -> Word32 -> Word32
Word32 -> Word32 -> Difference Word32
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Word64 where
    type Difference Word64 = Word64
    (-) = Word64 -> Word64 -> Word64
Word64 -> Word64 -> Difference Word64
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Word128 where
    type Difference Word128 = Word128
    (-) = Word128 -> Word128 -> Word128
Word128 -> Word128 -> Difference Word128
(Word128.-)
instance Subtractive Word256 where
    type Difference Word256 = Word256
    (-) = Word256 -> Word256 -> Word256
Word256 -> Word256 -> Difference Word256
(Word256.-)

instance Subtractive Prelude.Float where
    type Difference Prelude.Float = Prelude.Float
    (-) = Float -> Float -> Float
Float -> Float -> Difference Float
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Prelude.Double where
    type Difference Prelude.Double = Prelude.Double
    (-) = Double -> Double -> Double
Double -> Double -> Difference Double
forall a. Num a => a -> a -> a
(Prelude.-)

instance Subtractive Prelude.Char where
    type Difference Prelude.Char = Prelude.Int
    (-) Char
a Char
b = Int -> Int -> Int
forall a. Num a => a -> a -> a
(Prelude.-) (Char -> Int
charToInt Char
a) (Char -> Int
charToInt Char
b)
instance (KnownNat n, NatWithinBound Word64 n) => Subtractive (Zn64 n) where
    type Difference (Zn64 n) = Zn64 n
    (-) Zn64 n
a Zn64 n
b = Zn64 n -> Zn64 n -> Zn64 n
forall a. Num a => a -> a -> a
(Prelude.-) Zn64 n
a Zn64 n
b
instance KnownNat n => Subtractive (Zn n) where
    type Difference (Zn n) = Zn n
    (-) Zn n
a Zn n
b = Zn n -> Zn n -> Zn n
forall a. Num a => a -> a -> a
(Prelude.-) Zn n
a Zn n
b

instance Subtractive CChar where
    type Difference CChar = CChar
    (-) = CChar -> CChar -> CChar
CChar -> CChar -> Difference CChar
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CSChar where
    type Difference CSChar = CSChar
    (-) = CSChar -> CSChar -> CSChar
CSChar -> CSChar -> Difference CSChar
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CUChar where
    type Difference CUChar = CUChar
    (-) = CUChar -> CUChar -> CUChar
CUChar -> CUChar -> Difference CUChar
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CShort where
    type Difference CShort = CShort
    (-) = CShort -> CShort -> CShort
CShort -> CShort -> Difference CShort
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CUShort where
    type Difference CUShort = CUShort
    (-) = CUShort -> CUShort -> CUShort
CUShort -> CUShort -> Difference CUShort
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CInt where
    type Difference CInt = CInt
    (-) = CInt -> CInt -> CInt
CInt -> CInt -> Difference CInt
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CUInt where
    type Difference CUInt = CUInt
    (-) = CUInt -> CUInt -> CUInt
CUInt -> CUInt -> Difference CUInt
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CLong where
    type Difference CLong = CLong
    (-) = CLong -> CLong -> CLong
CLong -> CLong -> Difference CLong
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CULong where
    type Difference CULong = CULong
    (-) = CULong -> CULong -> CULong
CULong -> CULong -> Difference CULong
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CPtrdiff where
    type Difference CPtrdiff = CPtrdiff
    (-) = CPtrdiff -> CPtrdiff -> CPtrdiff
CPtrdiff -> CPtrdiff -> Difference CPtrdiff
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CSize where
    type Difference CSize = CSize
    (-) = CSize -> CSize -> CSize
CSize -> CSize -> Difference CSize
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CWchar where
    type Difference CWchar = CWchar
    (-) = CWchar -> CWchar -> CWchar
CWchar -> CWchar -> Difference CWchar
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CSigAtomic where
    type Difference CSigAtomic = CSigAtomic
    (-) = CSigAtomic -> CSigAtomic -> CSigAtomic
CSigAtomic -> CSigAtomic -> Difference CSigAtomic
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CLLong where
    type Difference CLLong = CLLong
    (-) = CLLong -> CLLong -> CLLong
CLLong -> CLLong -> Difference CLLong
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CULLong where
    type Difference CULLong = CULLong
    (-) = CULLong -> CULLong -> CULLong
CULLong -> CULLong -> Difference CULLong
forall a. Num a => a -> a -> a
(Prelude.-)
#if MIN_VERSION_base(4,10,0)
instance Subtractive CBool where
    type Difference CBool = CBool
    (-) = CBool -> CBool -> CBool
CBool -> CBool -> Difference CBool
forall a. Num a => a -> a -> a
(Prelude.-)
#endif
instance Subtractive CIntPtr where
    type Difference CIntPtr = CIntPtr
    (-) = CIntPtr -> CIntPtr -> CIntPtr
CIntPtr -> CIntPtr -> Difference CIntPtr
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CUIntPtr where
    type Difference CUIntPtr = CUIntPtr
    (-) = CUIntPtr -> CUIntPtr -> CUIntPtr
CUIntPtr -> CUIntPtr -> Difference CUIntPtr
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CIntMax where
    type Difference CIntMax = CIntMax
    (-) = CIntMax -> CIntMax -> CIntMax
CIntMax -> CIntMax -> Difference CIntMax
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CUIntMax where
    type Difference CUIntMax = CUIntMax
    (-) = CUIntMax -> CUIntMax -> CUIntMax
CUIntMax -> CUIntMax -> Difference CUIntMax
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CClock where
    type Difference CClock = CClock
    (-) = CClock -> CClock -> CClock
CClock -> CClock -> Difference CClock
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CTime where
    type Difference CTime = CTime
    (-) = CTime -> CTime -> CTime
CTime -> CTime -> Difference CTime
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CUSeconds where
    type Difference CUSeconds = CUSeconds
    (-) = CUSeconds -> CUSeconds -> CUSeconds
CUSeconds -> CUSeconds -> Difference CUSeconds
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CSUSeconds where
    type Difference CSUSeconds = CSUSeconds
    (-) = CSUSeconds -> CSUSeconds -> CSUSeconds
CSUSeconds -> CSUSeconds -> Difference CSUSeconds
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive COff where
    type Difference COff = COff
    (-) = COff -> COff -> COff
COff -> COff -> Difference COff
forall a. Num a => a -> a -> a
(Prelude.-)

instance Subtractive CFloat where
    type Difference CFloat = CFloat
    (-) = CFloat -> CFloat -> CFloat
CFloat -> CFloat -> Difference CFloat
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CDouble where
    type Difference CDouble = CDouble
    (-) = CDouble -> CDouble -> CDouble
CDouble -> CDouble -> Difference CDouble
forall a. Num a => a -> a -> a
(Prelude.-)