{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE TypeFamilies #-}
module Data.Monoids (module Data.Monoids, module X) where
import Prelude hiding (Monoid, mempty, mconcat)
import GHC.Exts (Constraint)
import qualified Data.Monoid as M
import Data.Semigroup as X (Semigroup, (<>), sconcat, stimes)
import Data.Map.Lazy (Map)
import qualified Data.Map.Lazy as Map
import qualified Data.Foldable as Foldable
class Mempty a where
mempty :: a
default mempty :: M.Monoid a => a
mempty = M.mempty ; {-# INLINE mempty #-}
instance {-# OVERLAPPABLE #-} M.Monoid a => Mempty a
type family Mempties lst :: Constraint where
Mempties '[] = ()
Mempties (a ': as) = (Mempty a, Mempties as)
mappend :: Semigroup a => a -> a -> a
mappend = (<>) ; {-# INLINE mappend #-}
mappendWith :: Semigroup a => a -> a -> a -> a
mappendWith m l r = l <> m <> r ; {-# INLINE mappendWith #-}
mappendBetween :: Semigroup a => a -> a -> a -> a
mappendBetween l r m = l <> m <> r ; {-# INLINE mappendBetween #-}
type family Semigroups lst :: Constraint where
Semigroups '[] = ()
Semigroups (a ': as) = (Semigroup a, Semigroups as)
class (Mempty a, Semigroup a) => Monoid a where
mconcat :: [a] -> a
mconcat = foldr (<>) mempty ; {-# INLINE mconcat #-}
instance {-# OVERLAPPABLE #-} (Mempty a, Semigroup a) => Monoid a
mconcat' :: (Foldable t, Monoid a) => t a -> a
mconcat' = foldr (<>) mempty ; {-# INLINE mconcat' #-}
intersperse :: Foldable f => a -> f a -> [a]
intersperse sep a = case Foldable.toList a of
[] -> []
(x:xs) -> x : prependToAll sep xs where
prependToAll sep = \case
[] -> []
(x:xs) -> sep : x : prependToAll sep xs
{-# INLINE intersperse #-}
intercalate :: (Monoid a, Foldable f) => a -> f a -> a
intercalate delim l = mconcat (intersperse delim l) ; {-# INLINE intercalate #-}
intercalate' :: Monoid a => a -> [a] -> a
intercalate' = intercalate ; {-# INLINE intercalate' #-}
type family Monoids lst :: Constraint where
Monoids '[] = ()
Monoids (a ': as) = (Monoid a, Monoids as)
instance Mempty [a] where mempty = []
instance Mempty (Maybe a) where mempty = Nothing
instance Mempty (Map k a) where mempty = Map.empty