{-# LANGUAGE CPP #-} #if MIN_VERSION_base(4,12,0) {-# LANGUAGE TypeOperators #-} #endif module Data.Semigroup.Commutative where import Data.IntSet (IntSet) import Data.Monoid import Data.Ord import Data.List (unfoldr) import Data.Set #if MIN_VERSION_base(4,7,0) import Data.Proxy #endif #if MIN_VERSION_base(4,9,0) && !MIN_VERSION_base(4,11,0) import Data.Semigroup (Semigroup(..)) #endif #if MIN_VERSION_base(4,9,0) import Data.Functor.Const import Data.Functor.Identity #endif #if MIN_VERSION_base(4,12,0) import Data.Functor.Contravariant (Op(Op)) import GHC.Generics #endif import Numeric.Product.Commutative ( CommutativeProduct ) -- |An 'Commutative' semigroup is a 'Semigroup' that follows the rule: -- -- @a \<> b == b \<> a@ class #if MIN_VERSION_base(4,9,0) Semigroup g #else Monoid g #endif => Commutative g -- | Trivial commutative semigroup. instance Commutative () -- | @since 0.0.1.0 instance Commutative a => Commutative (Maybe a) instance Num a => Commutative (Sum a) instance CommutativeProduct a => Commutative (Product a) instance Commutative a => Commutative (Dual a) -- | Functions lift commutative semigroups pointwise. instance Commutative b => Commutative (a -> b) -- | Product commutative semigroup. -- A Pair of commutative semigroups gives rise to a commutative semigroup instance (Commutative a, Commutative b) => Commutative (a, b) instance (Commutative a, Commutative b, Commutative c) => Commutative (a, b, c) instance (Commutative a, Commutative b, Commutative c, Commutative d) => Commutative (a, b, c, d) instance (Commutative a, Commutative b, Commutative c, Commutative d, Commutative e) => Commutative (a, b, c, d, e) -- | @since 0.0.2.0 instance Ord a => Commutative (Set a) -- | @since 0.0.2.0 instance Commutative IntSet #if MIN_VERSION_base(4,11,0) instance Commutative a => Commutative (Down a) #endif #if MIN_VERSION_base(4,7,0) -- | Trivial commutative semigroup, Functor style. instance Commutative (Proxy x) #endif -- 'Const' has existed for a long time, but the Monoid instance -- arrives in base-4.9.0.0. Similarly, 'Identity' was defined in -- base-4.8.0.0 but doesn't get the Monoid instance until base-4.9.0.0 #if MIN_VERSION_base(4,9,0) -- | 'Const' lifts commutative semigroups into a functor. instance Commutative a => Commutative (Const a x) -- | 'Identity' lifts commutative semigroups pointwise (at only one point). instance Commutative a => Commutative (Identity a) #endif -- (:*:) and (:.:) exist since base-4.6.0.0 but the Monoid instances -- arrive in base-4.12.0.0. -- Also, contravariant was moved into base in this version. #if MIN_VERSION_base(4,12,0) -- | Product of commutative semigroups, Functor style. instance (Commutative (f a), Commutative (g a)) => Commutative ((f :*: g) a) -- See https://gitlab.haskell.org/ghc/ghc/issues/11135#note_111802 for the reason Compose is not also provided. -- Base does not define Monoid (Compose f g a) so this is the best we can -- really do for functor composition. instance Commutative (f (g a)) => Commutative ((f :.: g) a) instance Commutative a => Commutative (Op a b) #endif