{-# 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 -> Difference Integer
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Int where
    type Difference Int = Int
    (-) = Int -> Int -> Difference Int
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Int8 where
    type Difference Int8 = Int8
    (-) = Int8 -> Int8 -> Difference Int8
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Int16 where
    type Difference Int16 = Int16
    (-) = Int16 -> Int16 -> Difference Int16
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Int32 where
    type Difference Int32 = Int32
    (-) = Int32 -> Int32 -> Difference Int32
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Int64 where
    type Difference 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     = 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 -> Difference Word
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Word8 where
    type Difference Word8 = Word8
    (-) = Word8 -> Word8 -> Difference Word8
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Word16 where
    type Difference Word16 = Word16
    (-) = Word16 -> Word16 -> Difference Word16
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Word32 where
    type Difference Word32 = Word32
    (-) = Word32 -> Word32 -> Difference Word32
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Word64 where
    type Difference 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 -> Difference Float
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive Prelude.Double where
    type Difference Prelude.Double = Prelude.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 -> Difference CChar
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CSChar where
    type Difference CSChar = CSChar
    (-) = CSChar -> CSChar -> Difference CSChar
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CUChar where
    type Difference CUChar = CUChar
    (-) = CUChar -> CUChar -> Difference CUChar
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CShort where
    type Difference CShort = CShort
    (-) = CShort -> CShort -> Difference CShort
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CUShort where
    type Difference CUShort = CUShort
    (-) = CUShort -> CUShort -> Difference CUShort
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CInt where
    type Difference CInt = CInt
    (-) = CInt -> CInt -> Difference CInt
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CUInt where
    type Difference CUInt = CUInt
    (-) = CUInt -> CUInt -> Difference CUInt
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CLong where
    type Difference CLong = CLong
    (-) = CLong -> CLong -> Difference CLong
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CULong where
    type Difference CULong = CULong
    (-) = CULong -> CULong -> Difference CULong
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CPtrdiff where
    type Difference CPtrdiff = CPtrdiff
    (-) = CPtrdiff -> CPtrdiff -> Difference CPtrdiff
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CSize where
    type Difference CSize = CSize
    (-) = CSize -> CSize -> Difference CSize
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CWchar where
    type Difference CWchar = CWchar
    (-) = CWchar -> CWchar -> Difference CWchar
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CSigAtomic where
    type Difference CSigAtomic = CSigAtomic
    (-) = CSigAtomic -> CSigAtomic -> Difference CSigAtomic
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CLLong where
    type Difference CLLong = CLLong
    (-) = CLLong -> CLLong -> Difference CLLong
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CULLong where
    type Difference 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 -> Difference CBool
forall a. Num a => a -> a -> a
(Prelude.-)
#endif
instance Subtractive CIntPtr where
    type Difference CIntPtr = CIntPtr
    (-) = CIntPtr -> CIntPtr -> Difference CIntPtr
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CUIntPtr where
    type Difference CUIntPtr = CUIntPtr
    (-) = CUIntPtr -> CUIntPtr -> Difference CUIntPtr
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CIntMax where
    type Difference CIntMax = CIntMax
    (-) = CIntMax -> CIntMax -> Difference CIntMax
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CUIntMax where
    type Difference CUIntMax = CUIntMax
    (-) = CUIntMax -> CUIntMax -> Difference CUIntMax
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CClock where
    type Difference CClock = CClock
    (-) = CClock -> CClock -> Difference CClock
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CTime where
    type Difference CTime = CTime
    (-) = CTime -> CTime -> Difference CTime
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CUSeconds where
    type Difference CUSeconds = CUSeconds
    (-) = CUSeconds -> CUSeconds -> Difference CUSeconds
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive CSUSeconds where
    type Difference CSUSeconds = CSUSeconds
    (-) = CSUSeconds -> CSUSeconds -> Difference CSUSeconds
forall a. Num a => a -> a -> a
(Prelude.-)
instance Subtractive COff where
    type Difference COff = COff
    (-) = COff -> COff -> Difference COff
forall a. Num a => a -> a -> a
(Prelude.-)

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