module Data.Accumulator
( Accumulator (..)
, singleton
, accumulateMany
, AccumulatorSemigroup (..)
) where
import qualified Data.Set as Set
import Data.Foldable (foldl')
import Data.Semigroup
#if !MIN_VERSION_base(4,8,0)
import Data.Foldable
#endif
class Accumulator acc x where
accumulate :: x -> acc -> acc
singleton :: (Accumulator acc x, Monoid acc) => x -> acc
singleton = flip accumulate mempty
accumulateMany :: (Foldable f, Accumulator acc x) => f x -> acc -> acc
accumulateMany xs acc = foldl' (flip accumulate) acc xs
instance Accumulator [a] a where
accumulate = (:)
instance Ord a => Accumulator (Set.Set a) a where
accumulate = Set.insert
instance Semigroup m => Accumulator (AccumulatorSemigroup m) (AccumulatorSemigroup m) where
accumulate = (<>)
newtype AccumulatorSemigroup a = AccumulatorSemigroup {getAccumulatorSemigroup :: a}
instance Semigroup m => Semigroup (AccumulatorSemigroup m) where
(<>) (AccumulatorSemigroup a) (AccumulatorSemigroup b) = AccumulatorSemigroup $ (<>) a b