{-# 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.Compat.Primitive
import Basement.Numerical.Number
import qualified Prelude
import GHC.Types (Float(..), Double(..))
import GHC.Prim (plusWord#, plusFloat#, (+#), (+##))
import qualified 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#
a Int# -> Int# -> Int#
`plusInt8#` 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#
a Int# -> Int# -> Int#
`plusInt16#` 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#
a Int# -> Int# -> Int#
`plusInt32#` 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
#if __GLASGOW_HASKELL__ >= 904
(I64# a) + (I64# b) = I64# (GHC.Prim.intToInt64# (GHC.Prim.int64ToInt# a +# GHC.Prim.int64ToInt# b))
#else
(I64# Int#
a) + :: Int64 -> Int64 -> Int64
+ (I64# Int#
b) = Int# -> Int64
I64# (Int#
a Int# -> Int# -> Int#
+# Int#
b)
#endif
#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#
a Word# -> Word# -> Word#
`plusWord8#` 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#
a Word# -> Word# -> Word#
`plusWord16#` 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#
a Word# -> Word# -> Word#
`plusWord32#` 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
#if __GLASGOW_HASKELL__ >= 904
(W64# a) + (W64# b) = W64# (GHC.Prim.wordToWord64# (GHC.Prim.word64ToWord# a `plusWord#` GHC.Prim.word64ToWord# b))
#else
(W64# Word#
a) + :: Word64 -> Word64 -> Word64
+ (W64# Word#
b) = Word# -> Word64
W64# (Word#
a Word# -> Word# -> Word#
`plusWord#` Word#
b)
#endif
#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