{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE DefaultSignatures #-}
{-# OPTIONS_GHC -fno-prof-auto #-}
module Basement.Numerical.Additive
( Additive(..)
) where
#include "MachDeps.h"
import Basement.Compat.Base
import Basement.Compat.C.Types
import Basement.Compat.Natural
import Basement.Numerical.Number
import qualified Prelude
import GHC.Types
import GHC.Prim
import GHC.Int
import GHC.Word
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
#if WORD_SIZE_IN_BITS < 64
import GHC.IntWord64
#endif
class Additive a where
{-# MINIMAL azero, (+) #-}
azero :: a
(+) :: a -> a -> a
scale :: IsNatural n => n -> a -> a
default scale :: (Enum n, IsNatural n) => n -> a -> a
scale = n -> a -> a
forall n a. (Enum n, IsNatural n, Additive a) => n -> a -> a
scaleEnum
scaleEnum :: (Enum n, IsNatural n, Additive a) => n -> a -> a
scaleEnum :: n -> a -> a
scaleEnum n
0 a
_ = a
forall a. Additive a => a
azero
scaleEnum n
1 a
a = a
a
scaleEnum n
2 a
a = a
a a -> a -> a
forall a. Additive a => a -> a -> a
+ a
a
scaleEnum n
n a
a = a
a a -> a -> a
forall a. Additive a => a -> a -> a
+ n -> a -> a
forall n a. (Enum n, IsNatural n, Additive a) => n -> a -> a
scaleEnum (n -> n
forall a. Enum a => a -> a
pred n
n) a
a
infixl 6 +
instance Additive Integer where
azero :: Integer
azero = Integer
0
+ :: Integer -> Integer -> Integer
(+) = Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> Integer -> Integer
scale = n -> Integer -> Integer
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Int where
azero :: Int
azero = Int
0
(I# Int#
a) + :: Int -> Int -> Int
+ (I# Int#
b) = Int# -> Int
I# (Int#
a Int# -> Int# -> Int#
+# Int#
b)
scale :: n -> Int -> Int
scale = n -> Int -> Int
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Int8 where
azero :: Int8
azero = Int8
0
(I8# Int#
a) + :: Int8 -> Int8 -> Int8
+ (I8# Int#
b) = Int# -> Int8
I8# (Int# -> Int#
narrow8Int# (Int#
a Int# -> Int# -> Int#
+# Int#
b))
scale :: n -> Int8 -> Int8
scale = n -> Int8 -> Int8
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Int16 where
azero :: Int16
azero = Int16
0
(I16# Int#
a) + :: Int16 -> Int16 -> Int16
+ (I16# Int#
b) = Int# -> Int16
I16# (Int# -> Int#
narrow16Int# (Int#
a Int# -> Int# -> Int#
+# Int#
b))
scale :: n -> Int16 -> Int16
scale = n -> Int16 -> Int16
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Int32 where
azero :: Int32
azero = Int32
0
(I32# Int#
a) + :: Int32 -> Int32 -> Int32
+ (I32# Int#
b) = Int# -> Int32
I32# (Int# -> Int#
narrow32Int# (Int#
a Int# -> Int# -> Int#
+# Int#
b))
scale :: n -> Int32 -> Int32
scale = n -> Int32 -> Int32
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Int64 where
azero :: Int64
azero = Int64
0
#if WORD_SIZE_IN_BITS == 64
(I64# Int#
a) + :: Int64 -> Int64 -> Int64
+ (I64# Int#
b) = Int# -> Int64
I64# (Int#
a Int# -> Int# -> Int#
+# Int#
b)
#else
(I64# a) + (I64# b) = I64# (a `plusInt64#` b)
#endif
scale :: n -> Int64 -> Int64
scale = n -> Int64 -> Int64
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Word where
azero :: Word
azero = Word
0
(W# Word#
a) + :: Word -> Word -> Word
+ (W# Word#
b) = Word# -> Word
W# (Word#
a Word# -> Word# -> Word#
`plusWord#` Word#
b)
scale :: n -> Word -> Word
scale = n -> Word -> Word
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Natural where
azero :: Natural
azero = Natural
0
+ :: Natural -> Natural -> Natural
(+) = Natural -> Natural -> Natural
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> Natural -> Natural
scale = n -> Natural -> Natural
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Word8 where
azero :: Word8
azero = Word8
0
(W8# Word#
a) + :: Word8 -> Word8 -> Word8
+ (W8# Word#
b) = Word# -> Word8
W8# (Word# -> Word#
narrow8Word# (Word#
a Word# -> Word# -> Word#
`plusWord#` Word#
b))
scale :: n -> Word8 -> Word8
scale = n -> Word8 -> Word8
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Word16 where
azero :: Word16
azero = Word16
0
(W16# Word#
a) + :: Word16 -> Word16 -> Word16
+ (W16# Word#
b) = Word# -> Word16
W16# (Word# -> Word#
narrow16Word# (Word#
a Word# -> Word# -> Word#
`plusWord#` Word#
b))
scale :: n -> Word16 -> Word16
scale = n -> Word16 -> Word16
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Word32 where
azero :: Word32
azero = Word32
0
(W32# Word#
a) + :: Word32 -> Word32 -> Word32
+ (W32# Word#
b) = Word# -> Word32
W32# (Word# -> Word#
narrow32Word# (Word#
a Word# -> Word# -> Word#
`plusWord#` Word#
b))
scale :: n -> Word32 -> Word32
scale = n -> Word32 -> Word32
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Word64 where
azero :: Word64
azero = Word64
0
#if WORD_SIZE_IN_BITS == 64
(W64# Word#
a) + :: Word64 -> Word64 -> Word64
+ (W64# Word#
b) = Word# -> Word64
W64# (Word#
a Word# -> Word# -> Word#
`plusWord#` Word#
b)
#else
(W64# a) + (W64# b) = W64# (int64ToWord64# (word64ToInt64# a `plusInt64#` word64ToInt64# b))
#endif
scale :: n -> Word64 -> Word64
scale = n -> Word64 -> Word64
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Word128 where
azero :: Word128
azero = Word128
0
+ :: Word128 -> Word128 -> Word128
(+) = Word128 -> Word128 -> Word128
(Word128.+)
scale :: n -> Word128 -> Word128
scale = n -> Word128 -> Word128
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Word256 where
azero :: Word256
azero = Word256
0
+ :: Word256 -> Word256 -> Word256
(+) = Word256 -> Word256 -> Word256
(Word256.+)
scale :: n -> Word256 -> Word256
scale = n -> Word256 -> Word256
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Prelude.Float where
azero :: Float
azero = Float
0.0
(F# Float#
a) + :: Float -> Float -> Float
+ (F# Float#
b) = Float# -> Float
F# (Float#
a Float# -> Float# -> Float#
`plusFloat#` Float#
b)
scale :: n -> Float -> Float
scale = n -> Float -> Float
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Prelude.Double where
azero :: Double
azero = Double
0.0
(D# Double#
a) + :: Double -> Double -> Double
+ (D# Double#
b) = Double# -> Double
D# (Double#
a Double# -> Double# -> Double#
+## Double#
b)
scale :: n -> Double -> Double
scale = n -> Double -> Double
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Prelude.Rational where
azero :: Rational
azero = Rational
0.0
+ :: Rational -> Rational -> Rational
(+) = Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> Rational -> Rational
scale = n -> Rational -> Rational
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance (KnownNat n, NatWithinBound Word64 n) => Additive (Zn64 n) where
azero :: Zn64 n
azero = Word64 -> Zn64 n
forall (n :: Nat).
(KnownNat n, NatWithinBound Word64 n) =>
Word64 -> Zn64 n
zn64 Word64
0
+ :: Zn64 n -> Zn64 n -> Zn64 n
(+) = Zn64 n -> Zn64 n -> Zn64 n
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> Zn64 n -> Zn64 n
scale = n -> Zn64 n -> Zn64 n
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance KnownNat n => Additive (Zn n) where
azero :: Zn n
azero = Natural -> Zn n
forall (n :: Nat). KnownNat n => Natural -> Zn n
zn Natural
0
+ :: Zn n -> Zn n -> Zn n
(+) = Zn n -> Zn n -> Zn n
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> Zn n -> Zn n
scale = n -> Zn n -> Zn n
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CChar where
azero :: CChar
azero = CChar
0
+ :: CChar -> CChar -> CChar
(+) = CChar -> CChar -> CChar
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CChar -> CChar
scale = n -> CChar -> CChar
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CSChar where
azero :: CSChar
azero = CSChar
0
+ :: CSChar -> CSChar -> CSChar
(+) = CSChar -> CSChar -> CSChar
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CSChar -> CSChar
scale = n -> CSChar -> CSChar
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CUChar where
azero :: CUChar
azero = CUChar
0
+ :: CUChar -> CUChar -> CUChar
(+) = CUChar -> CUChar -> CUChar
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CUChar -> CUChar
scale = n -> CUChar -> CUChar
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CShort where
azero :: CShort
azero = CShort
0
+ :: CShort -> CShort -> CShort
(+) = CShort -> CShort -> CShort
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CShort -> CShort
scale = n -> CShort -> CShort
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CUShort where
azero :: CUShort
azero = CUShort
0
+ :: CUShort -> CUShort -> CUShort
(+) = CUShort -> CUShort -> CUShort
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CUShort -> CUShort
scale = n -> CUShort -> CUShort
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CInt where
azero :: CInt
azero = CInt
0
+ :: CInt -> CInt -> CInt
(+) = CInt -> CInt -> CInt
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CInt -> CInt
scale = n -> CInt -> CInt
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CUInt where
azero :: CUInt
azero = CUInt
0
+ :: CUInt -> CUInt -> CUInt
(+) = CUInt -> CUInt -> CUInt
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CUInt -> CUInt
scale = n -> CUInt -> CUInt
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CLong where
azero :: CLong
azero = CLong
0
+ :: CLong -> CLong -> CLong
(+) = CLong -> CLong -> CLong
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CLong -> CLong
scale = n -> CLong -> CLong
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CULong where
azero :: CULong
azero = CULong
0
+ :: CULong -> CULong -> CULong
(+) = CULong -> CULong -> CULong
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CULong -> CULong
scale = n -> CULong -> CULong
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CPtrdiff where
azero :: CPtrdiff
azero = CPtrdiff
0
+ :: CPtrdiff -> CPtrdiff -> CPtrdiff
(+) = CPtrdiff -> CPtrdiff -> CPtrdiff
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CPtrdiff -> CPtrdiff
scale = n -> CPtrdiff -> CPtrdiff
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CSize where
azero :: CSize
azero = CSize
0
+ :: CSize -> CSize -> CSize
(+) = CSize -> CSize -> CSize
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CSize -> CSize
scale = n -> CSize -> CSize
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CWchar where
azero :: CWchar
azero = CWchar
0
+ :: CWchar -> CWchar -> CWchar
(+) = CWchar -> CWchar -> CWchar
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CWchar -> CWchar
scale = n -> CWchar -> CWchar
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CSigAtomic where
azero :: CSigAtomic
azero = CSigAtomic
0
+ :: CSigAtomic -> CSigAtomic -> CSigAtomic
(+) = CSigAtomic -> CSigAtomic -> CSigAtomic
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CSigAtomic -> CSigAtomic
scale = n -> CSigAtomic -> CSigAtomic
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CLLong where
azero :: CLLong
azero = CLLong
0
+ :: CLLong -> CLLong -> CLLong
(+) = CLLong -> CLLong -> CLLong
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CLLong -> CLLong
scale = n -> CLLong -> CLLong
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CULLong where
azero :: CULLong
azero = CULLong
0
+ :: CULLong -> CULLong -> CULLong
(+) = CULLong -> CULLong -> CULLong
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CULLong -> CULLong
scale = n -> CULLong -> CULLong
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CIntPtr where
azero :: CIntPtr
azero = CIntPtr
0
+ :: CIntPtr -> CIntPtr -> CIntPtr
(+) = CIntPtr -> CIntPtr -> CIntPtr
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CIntPtr -> CIntPtr
scale = n -> CIntPtr -> CIntPtr
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CUIntPtr where
azero :: CUIntPtr
azero = CUIntPtr
0
+ :: CUIntPtr -> CUIntPtr -> CUIntPtr
(+) = CUIntPtr -> CUIntPtr -> CUIntPtr
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CUIntPtr -> CUIntPtr
scale = n -> CUIntPtr -> CUIntPtr
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CIntMax where
azero :: CIntMax
azero = CIntMax
0
+ :: CIntMax -> CIntMax -> CIntMax
(+) = CIntMax -> CIntMax -> CIntMax
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CIntMax -> CIntMax
scale = n -> CIntMax -> CIntMax
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CUIntMax where
azero :: CUIntMax
azero = CUIntMax
0
+ :: CUIntMax -> CUIntMax -> CUIntMax
(+) = CUIntMax -> CUIntMax -> CUIntMax
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CUIntMax -> CUIntMax
scale = n -> CUIntMax -> CUIntMax
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CClock where
azero :: CClock
azero = CClock
0
+ :: CClock -> CClock -> CClock
(+) = CClock -> CClock -> CClock
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CClock -> CClock
scale = n -> CClock -> CClock
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CTime where
azero :: CTime
azero = CTime
0
+ :: CTime -> CTime -> CTime
(+) = CTime -> CTime -> CTime
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CTime -> CTime
scale = n -> CTime -> CTime
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CUSeconds where
azero :: CUSeconds
azero = CUSeconds
0
+ :: CUSeconds -> CUSeconds -> CUSeconds
(+) = CUSeconds -> CUSeconds -> CUSeconds
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CUSeconds -> CUSeconds
scale = n -> CUSeconds -> CUSeconds
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CSUSeconds where
azero :: CSUSeconds
azero = CSUSeconds
0
+ :: CSUSeconds -> CSUSeconds -> CSUSeconds
(+) = CSUSeconds -> CSUSeconds -> CSUSeconds
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CSUSeconds -> CSUSeconds
scale = n -> CSUSeconds -> CSUSeconds
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive COff where
azero :: COff
azero = COff
0
+ :: COff -> COff -> COff
(+) = COff -> COff -> COff
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> COff -> COff
scale = n -> COff -> COff
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CFloat where
azero :: CFloat
azero = CFloat
0
+ :: CFloat -> CFloat -> CFloat
(+) = CFloat -> CFloat -> CFloat
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CFloat -> CFloat
scale = n -> CFloat -> CFloat
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CDouble where
azero :: CDouble
azero = CDouble
0
+ :: CDouble -> CDouble -> CDouble
(+) = CDouble -> CDouble -> CDouble
forall a. Num a => a -> a -> a
(Prelude.+)
scale :: n -> CDouble -> CDouble
scale = n -> CDouble -> CDouble
forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
scaleNum :: (Prelude.Num a, IsNatural n) => n -> a -> a
scaleNum :: n -> a -> a
scaleNum n
n a
a = (Natural -> a
forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral (Natural -> a) -> Natural -> a
forall a b. (a -> b) -> a -> b
$ n -> Natural
forall a. IsNatural a => a -> Natural
toNatural n
n) a -> a -> a
forall a. Num a => a -> a -> a
Prelude.* a
a