    {-# 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.-)