{-# 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 = forall n a. (Enum n, IsNatural n, Additive a) => n -> a -> a
scaleEnum
scaleEnum :: (Enum n, IsNatural n, Additive a) => n -> a -> a
scaleEnum :: forall n a. (Enum n, IsNatural n, Additive a) => n -> a -> a
scaleEnum n
0 a
_ = forall a. Additive a => a
azero
scaleEnum n
1 a
a = a
a
scaleEnum n
2 a
a = a
a forall a. Additive a => a -> a -> a
+ a
a
scaleEnum n
n a
a = a
a forall a. Additive a => a -> a -> a
+ forall n a. (Enum n, IsNatural n, Additive a) => n -> a -> a
scaleEnum (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
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> Integer -> Integer
scale = 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 :: forall n. IsNatural n => n -> Int -> Int
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Int8 where
azero :: Int8
azero = Int8
0
(I8# Int8#
a) + :: Int8 -> Int8 -> Int8
+ (I8# Int8#
b) = Int8# -> Int8
I8# (Int8#
a Int8# -> Int8# -> Int8#
`plusInt8#` Int8#
b)
scale :: forall n. IsNatural n => n -> Int8 -> Int8
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Int16 where
azero :: Int16
azero = Int16
0
(I16# Int16#
a) + :: Int16 -> Int16 -> Int16
+ (I16# Int16#
b) = Int16# -> Int16
I16# (Int16#
a Int16# -> Int16# -> Int16#
`plusInt16#` Int16#
b)
scale :: forall n. IsNatural n => n -> Int16 -> Int16
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Int32 where
azero :: Int32
azero = Int32
0
(I32# Int32#
a) + :: Int32 -> Int32 -> Int32
+ (I32# Int32#
b) = Int32# -> Int32
I32# (Int32#
a Int32# -> Int32# -> Int32#
`plusInt32#` Int32#
b)
scale :: forall n. IsNatural n => n -> Int32 -> Int32
scale = 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 :: forall n. IsNatural n => n -> Int64 -> Int64
scale = 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 :: forall n. IsNatural n => n -> Word -> Word
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Natural where
azero :: Natural
azero = Natural
0
+ :: Natural -> Natural -> Natural
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> Natural -> Natural
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Word8 where
azero :: Word8
azero = Word8
0
(W8# Word8#
a) + :: Word8 -> Word8 -> Word8
+ (W8# Word8#
b) = Word8# -> Word8
W8# (Word8#
a Word8# -> Word8# -> Word8#
`plusWord8#` Word8#
b)
scale :: forall n. IsNatural n => n -> Word8 -> Word8
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Word16 where
azero :: Word16
azero = Word16
0
(W16# Word16#
a) + :: Word16 -> Word16 -> Word16
+ (W16# Word16#
b) = Word16# -> Word16
W16# (Word16#
a Word16# -> Word16# -> Word16#
`plusWord16#` Word16#
b)
scale :: forall n. IsNatural n => n -> Word16 -> Word16
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive Word32 where
azero :: Word32
azero = Word32
0
(W32# Word32#
a) + :: Word32 -> Word32 -> Word32
+ (W32# Word32#
b) = Word32# -> Word32
W32# (Word32#
a Word32# -> Word32# -> Word32#
`plusWord32#` Word32#
b)
scale :: forall n. IsNatural n => n -> Word32 -> Word32
scale = 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 :: forall n. IsNatural n => n -> Word64 -> Word64
scale = 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 :: forall n. IsNatural n => n -> Word128 -> Word128
scale = 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 :: forall n. IsNatural n => n -> Word256 -> Word256
scale = 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 :: forall n. IsNatural n => n -> Float -> Float
scale = 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 :: forall n. IsNatural n => n -> Double -> Double
scale = 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
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> Rational -> Rational
scale = 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 = forall (n :: Natural).
(KnownNat n, NatWithinBound Word64 n) =>
Word64 -> Zn64 n
zn64 Word64
0
+ :: Zn64 n -> Zn64 n -> Zn64 n
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> Zn64 n -> Zn64 n
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance KnownNat n => Additive (Zn n) where
azero :: Zn n
azero = forall (n :: Natural). KnownNat n => Natural -> Zn n
zn Natural
0
+ :: Zn n -> Zn n -> Zn n
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> Zn n -> Zn n
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CChar where
azero :: CChar
azero = CChar
0
+ :: CChar -> CChar -> CChar
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CChar -> CChar
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CSChar where
azero :: CSChar
azero = CSChar
0
+ :: CSChar -> CSChar -> CSChar
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CSChar -> CSChar
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CUChar where
azero :: CUChar
azero = CUChar
0
+ :: CUChar -> CUChar -> CUChar
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CUChar -> CUChar
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CShort where
azero :: CShort
azero = CShort
0
+ :: CShort -> CShort -> CShort
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CShort -> CShort
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CUShort where
azero :: CUShort
azero = CUShort
0
+ :: CUShort -> CUShort -> CUShort
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CUShort -> CUShort
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CInt where
azero :: CInt
azero = CInt
0
+ :: CInt -> CInt -> CInt
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CInt -> CInt
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CUInt where
azero :: CUInt
azero = CUInt
0
+ :: CUInt -> CUInt -> CUInt
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CUInt -> CUInt
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CLong where
azero :: CLong
azero = CLong
0
+ :: CLong -> CLong -> CLong
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CLong -> CLong
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CULong where
azero :: CULong
azero = CULong
0
+ :: CULong -> CULong -> CULong
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CULong -> CULong
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CPtrdiff where
azero :: CPtrdiff
azero = CPtrdiff
0
+ :: CPtrdiff -> CPtrdiff -> CPtrdiff
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CPtrdiff -> CPtrdiff
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CSize where
azero :: CSize
azero = CSize
0
+ :: CSize -> CSize -> CSize
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CSize -> CSize
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CWchar where
azero :: CWchar
azero = CWchar
0
+ :: CWchar -> CWchar -> CWchar
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CWchar -> CWchar
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CSigAtomic where
azero :: CSigAtomic
azero = CSigAtomic
0
+ :: CSigAtomic -> CSigAtomic -> CSigAtomic
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CSigAtomic -> CSigAtomic
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CLLong where
azero :: CLLong
azero = CLLong
0
+ :: CLLong -> CLLong -> CLLong
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CLLong -> CLLong
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CULLong where
azero :: CULLong
azero = CULLong
0
+ :: CULLong -> CULLong -> CULLong
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CULLong -> CULLong
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CIntPtr where
azero :: CIntPtr
azero = CIntPtr
0
+ :: CIntPtr -> CIntPtr -> CIntPtr
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CIntPtr -> CIntPtr
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CUIntPtr where
azero :: CUIntPtr
azero = CUIntPtr
0
+ :: CUIntPtr -> CUIntPtr -> CUIntPtr
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CUIntPtr -> CUIntPtr
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CIntMax where
azero :: CIntMax
azero = CIntMax
0
+ :: CIntMax -> CIntMax -> CIntMax
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CIntMax -> CIntMax
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CUIntMax where
azero :: CUIntMax
azero = CUIntMax
0
+ :: CUIntMax -> CUIntMax -> CUIntMax
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CUIntMax -> CUIntMax
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CClock where
azero :: CClock
azero = CClock
0
+ :: CClock -> CClock -> CClock
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CClock -> CClock
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CTime where
azero :: CTime
azero = CTime
0
+ :: CTime -> CTime -> CTime
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CTime -> CTime
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CUSeconds where
azero :: CUSeconds
azero = CUSeconds
0
+ :: CUSeconds -> CUSeconds -> CUSeconds
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CUSeconds -> CUSeconds
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CSUSeconds where
azero :: CSUSeconds
azero = CSUSeconds
0
+ :: CSUSeconds -> CSUSeconds -> CSUSeconds
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CSUSeconds -> CSUSeconds
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive COff where
azero :: COff
azero = COff
0
+ :: COff -> COff -> COff
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> COff -> COff
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CFloat where
azero :: CFloat
azero = CFloat
0
+ :: CFloat -> CFloat -> CFloat
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CFloat -> CFloat
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
instance Additive CDouble where
azero :: CDouble
azero = CDouble
0
+ :: CDouble -> CDouble -> CDouble
(+) = forall a. Num a => a -> a -> a
(Prelude.+)
scale :: forall n. IsNatural n => n -> CDouble -> CDouble
scale = forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum
scaleNum :: (Prelude.Num a, IsNatural n) => n -> a -> a
scaleNum :: forall a n. (Num a, IsNatural n) => n -> a -> a
scaleNum n
n a
a = (forall a b. (Integral a, Num b) => a -> b
Prelude.fromIntegral forall a b. (a -> b) -> a -> b
$ forall a. IsNatural a => a -> Natural
toNatural n
n) forall a. Num a => a -> a -> a
Prelude.* a
a