module Foundation.Numerical.Additive
( Additive(..)
) where
#include "MachDeps.h"
import Foundation.Internal.Base
import Foundation.Internal.Natural
import Foundation.Numerical.Number
import qualified Prelude
import GHC.Types
import GHC.Prim
import GHC.Int
import GHC.Word
import Foreign.C.Types
#if WORD_SIZE_IN_BITS < 64
import GHC.IntWord64
#endif
class Additive a where
azero :: a
(+) :: a -> a -> a
scale :: IsNatural n => n -> a -> a
scale 0 _ = azero
scale 1 a = a
scale 2 a = a + a
scale n a = a + scale (pred n) a
infixl 6 +
instance Additive Integer where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive Int where
azero = 0
(I# a) + (I# b) = I# (a +# b)
scale = scaleNum
instance Additive Int8 where
azero = 0
(I8# a) + (I8# b) = I8# (narrow8Int# (a +# b))
scale = scaleNum
instance Additive Int16 where
azero = 0
(I16# a) + (I16# b) = I16# (narrow16Int# (a +# b))
scale = scaleNum
instance Additive Int32 where
azero = 0
(I32# a) + (I32# b) = I32# (narrow32Int# (a +# b))
scale = scaleNum
instance Additive Int64 where
azero = 0
#if WORD_SIZE_IN_BITS == 64
(I64# a) + (I64# b) = I64# (a +# b)
#else
(I64# a) + (I64# b) = I64# (a `plusInt64#` b)
#endif
scale = scaleNum
instance Additive Word where
azero = 0
(W# a) + (W# b) = W# (a `plusWord#` b)
scale = scaleNum
instance Additive Natural where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
instance Additive Word8 where
azero = 0
(W8# a) + (W8# b) = W8# (narrow8Word# (a `plusWord#` b))
scale = scaleNum
instance Additive Word16 where
azero = 0
(W16# a) + (W16# b) = W16# (narrow16Word# (a `plusWord#` b))
scale = scaleNum
instance Additive Word32 where
azero = 0
(W32# a) + (W32# b) = W32# (narrow32Word# (a `plusWord#` b))
scale = scaleNum
instance Additive Word64 where
azero = 0
#if WORD_SIZE_IN_BITS == 64
(W64# a) + (W64# b) = W64# (a `plusWord#` b)
#else
(W64# a) + (W64# b) = W64# (int64ToWord64# (word64ToInt64# a `plusInt64#` word64ToInt64# b))
#endif
scale = scaleNum
instance Additive Prelude.Float where
azero = 0.0
(F# a) + (F# b) = F# (a `plusFloat#` b)
scale = scaleNum
instance Additive Prelude.Double where
azero = 0.0
(D# a) + (D# b) = D# (a +## b)
scale = scaleNum
instance Additive CSize where
azero = 0
(+) = (Prelude.+)
scale = scaleNum
scaleNum :: (Prelude.Num a, IsNatural n) => n -> a -> a
scaleNum n a = (Prelude.fromIntegral $ toNatural n) Prelude.* a