module Numeric.Semigroup.Additive
(
Additive(..)
, sum1
) where
import qualified Prelude
import Prelude hiding ((+), replicate)
import Data.Int
import Data.Word
import Data.Semigroup.Foldable
import Data.Foldable
import Numeric.Natural.Internal
infixl 6 +
class Additive r where
(+) :: r -> r -> r
replicate1p :: Whole n => n -> r -> r
replicate1p y0 x0 = f x0 (1 Prelude.+ y0)
where
f x y
| even y = f (x + x) (y `quot` 2)
| y == 1 = x
| otherwise = g (x + x) (unsafePred y `quot` 2) x
g x y z
| even y = g (x + x) (y `quot` 2) z
| y == 1 = x + z
| otherwise = g (x + x) (unsafePred y `quot` 2) (x + z)
sumWith1 :: Foldable1 f => (a -> r) -> f a -> r
sumWith1 f = maybe (error "Numeric.Additive.Semigroup.sumWith1: empty structure") id . foldl' mf Nothing
where mf Nothing y = Just $! f y
mf (Just x) y = Just $! x + f y
sum1 :: (Foldable1 f, Additive r) => f r -> r
sum1 = sumWith1 id
instance Additive r => Additive (b -> r) where
f + g = \e -> f e + g e
replicate1p n f e = replicate1p n (f e)
sumWith1 f xs e = sumWith1 (`f` e) xs
instance Additive Bool where
(+) = (||)
replicate1p _ a = a
instance Additive Natural where
(+) = (Prelude.+)
replicate1p n r = (1 Prelude.+ toNatural n) * r
instance Additive Integer where
(+) = (Prelude.+)
replicate1p n r = (1 Prelude.+ toInteger n) * r
instance Additive Int where
(+) = (Prelude.+)
replicate1p n r = fromIntegral (1 Prelude.+ n) * r
instance Additive Int8 where
(+) = (Prelude.+)
replicate1p n r = fromIntegral (1 Prelude.+ n) * r
instance Additive Int16 where
(+) = (Prelude.+)
replicate1p n r = fromIntegral (1 Prelude.+ n) * r
instance Additive Int32 where
(+) = (Prelude.+)
replicate1p n r = fromIntegral (1 Prelude.+ n) * r
instance Additive Int64 where
(+) = (Prelude.+)
replicate1p n r = fromIntegral (1 Prelude.+ n) * r
instance Additive Word where
(+) = (Prelude.+)
replicate1p n r = fromIntegral (1 Prelude.+ n) * r
instance Additive Word8 where
(+) = (Prelude.+)
replicate1p n r = fromIntegral (1 Prelude.+ n) * r
instance Additive Word16 where
(+) = (Prelude.+)
replicate1p n r = fromIntegral (1 Prelude.+ n) * r
instance Additive Word32 where
(+) = (Prelude.+)
replicate1p n r = fromIntegral (1 Prelude.+ n) * r
instance Additive Word64 where
(+) = (Prelude.+)
replicate1p n r = fromIntegral (1 Prelude.+ n) * r
instance Additive () where
_ + _ = ()
replicate1p _ _ = ()
sumWith1 _ _ = ()
instance (Additive a, Additive b) => Additive (a,b) where
(a,b) + (i,j) = (a + i, b + j)
replicate1p n (a,b) = (replicate1p n a, replicate1p n b)
instance (Additive a, Additive b, Additive c) => Additive (a,b,c) where
(a,b,c) + (i,j,k) = (a + i, b + j, c + k)
replicate1p n (a,b,c) = (replicate1p n a, replicate1p n b, replicate1p n c)
instance (Additive a, Additive b, Additive c, Additive d) => Additive (a,b,c,d) where
(a,b,c,d) + (i,j,k,l) = (a + i, b + j, c + k, d + l)
replicate1p n (a,b,c,d) = (replicate1p n a, replicate1p n b, replicate1p n c, replicate1p n d)
instance (Additive a, Additive b, Additive c, Additive d, Additive e) => Additive (a,b,c,d,e) where
(a,b,c,d,e) + (i,j,k,l,m) = (a + i, b + j, c + k, d + l, e + m)
replicate1p n (a,b,c,d,e) = (replicate1p n a, replicate1p n b, replicate1p n c, replicate1p n d, replicate1p n e)