module Control.Additive
( Additive (..),
sum,
Adding (..),
Monoidaly (..),
Alternatively (..),
)
where
import Control.Applicative qualified as Applicative
import Prelude hiding (sum)
class Additive a where
empty :: a
(<|>) :: a -> a -> a
infixl 3 <|>
sum :: (Additive a, Foldable f) => f a -> a
sum :: forall a (f :: * -> *). (Additive a, Foldable f) => f a -> a
sum = (a -> a -> a) -> a -> f a -> a
forall a b. (a -> b -> b) -> b -> f a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> a -> a
forall a. Additive a => a -> a -> a
(<|>) a
forall a. Additive a => a
empty
newtype Adding a = Adding a
instance (Additive a) => Monoid (Adding a) where
mempty :: Adding a
mempty = a -> Adding a
forall a. a -> Adding a
Adding a
forall a. Additive a => a
empty
instance (Additive a) => Semigroup (Adding a) where
Adding a
a <> :: Adding a -> Adding a -> Adding a
<> Adding a
b = a -> Adding a
forall a. a -> Adding a
Adding (a
a a -> a -> a
forall a. Additive a => a -> a -> a
<|> a
b)
newtype Monoidaly a = Monoidaly a
instance (Monoid a) => Additive (Monoidaly a) where
empty :: Monoidaly a
empty = a -> Monoidaly a
forall a. a -> Monoidaly a
Monoidaly a
forall a. Monoid a => a
mempty
Monoidaly a
a <|> :: Monoidaly a -> Monoidaly a -> Monoidaly a
<|> Monoidaly a
b = a -> Monoidaly a
forall a. a -> Monoidaly a
Monoidaly (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b)
newtype Alternatively f a = Alternatively (f a)
instance (Applicative.Alternative f) => Additive (Alternatively f a) where
empty :: Alternatively f a
empty = f a -> Alternatively f a
forall {k} (f :: k -> *) (a :: k). f a -> Alternatively f a
Alternatively f a
forall a. f a
forall (f :: * -> *) a. Alternative f => f a
Applicative.empty
Alternatively f a
a <|> :: Alternatively f a -> Alternatively f a -> Alternatively f a
<|> Alternatively f a
b = f a -> Alternatively f a
forall {k} (f :: k -> *) (a :: k). f a -> Alternatively f a
Alternatively (f a
a f a -> f a -> f a
forall a. f a -> f a -> f a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
Applicative.<|> f a
b)