{-# language TypeApplications, ScopedTypeVariables #-} module Data.DifferenceList where import Data.Coerce (coerce) import Data.Foldable (Foldable (toList)) newtype DifferenceList a = DifferenceList ([a] -> [a]) instance Semigroup (DifferenceList a) where (<>) = coerce @(([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]) -- ignore (.) instance Monoid (DifferenceList a) where mempty = coerce @([a] -> [a]) -- ignore id instance Foldable DifferenceList where toList (DifferenceList differenceList) = differenceList [] foldr f initial = foldr f initial . toList singleton :: a -> DifferenceList a singleton = DifferenceList . (:)