Semigroup -package:semigroupoids

The class of semigroups (types with an associative binary operation). Instances should satisfy the following:
  • Associativity x <> (y <> z) = (x <> y) <> z
You can alternatively define sconcat instead of (<>), in which case the laws are:
A type a is a Semigroup if it provides an associative function (<>) that lets you combine any two values of type a into one. Where being associative means that the following must always hold:
(a <> b) <> c == a <> (b <> c)

Examples

The Min Semigroup instance for Int is defined to always pick the smaller number:
>>> Min 1 <> Min 2 <> Min 3 <> Min 4 :: Min Int
Min {getMin = 1}
If we need to combine multiple values we can use the sconcat function to do so. We need to ensure however that we have at least one value to operate on, since otherwise our result would be undefined. It is for this reason that sconcat uses Data.List.NonEmpty.NonEmpty - a list that can never be empty:
>>> (1 :| [])
1 :| []
  • - equivalent to [1] but guaranteed to be non-empty.
>>> (1 :| [2, 3, 4])
1 :| [2,3,4]
  • - equivalent to [1,2,3,4] but guaranteed to be non-empty.
Equipped with this guaranteed to be non-empty data structure, we can combine values using sconcat and a Semigroup of our choosing. We can try the Min and Max instances of Int which pick the smallest, or largest number respectively:
>>> sconcat (1 :| [2, 3, 4]) :: Min Int
Min {getMin = 1}
>>> sconcat (1 :| [2, 3, 4]) :: Max Int
Max {getMax = 4}
String concatenation is another example of a Semigroup instance:
>>> "foo" <> "bar"
"foobar"
A Semigroup is a generalization of a Monoid. Yet unlike the Semigroup, the Monoid requires the presence of a neutral element (mempty) in addition to the associative operator. The requirement for a neutral element prevents many types from being a full Monoid, like Data.List.NonEmpty.NonEmpty. Note that the use of (<>) in this module conflicts with an operator with the same name that is being exported by Data.Monoid. However, this package re-exports (most of) the contents of Data.Monoid, so to use semigroups and monoids in the same package just
import Data.Semigroup
The class of semigroups (types with an associative binary operation). Instances should satisfy the following:
  • Associativity x <> (y <> z) = (x <> y) <> z
You can alternatively define sconcat instead of (<>), in which case the laws are:
The class of semigroups (types with an associative binary operation). Instances should satisfy the following:
  • Associativity x <> (y <> z) = (x <> y) <> z
You can alternatively define sconcat instead of (<>), in which case the laws are: @since base-4.9.0.0
The class of semigroups (types with an associative binary operation). Instances should satisfy the following:
  • Associativity x <> (y <> z) = (x <> y) <> z
TextShow instances for data types in the Data.Semigroup module. Since: 3
Compatibility layer for Data.Semigroup
Some semigroup instances used in several places
Eliminator functions for data types in Data.Semigroup. All of these are re-exported from Data.Eliminator with the following exceptions:
Not on Stackage, so not searched. A semigroup
This module provides the ability to append two records using (<>), provided that all of their fields have an instance of Semigroup.
Properties to check that the Semigroup a satisfies the semigroup properties. The argument value is ignored and is present only for its type.
Category sans id
Convert bijections to and from semigroupoids Iso.
For different Associative t, we have functors f that we can "squash", using biretract:
t f f ~> f
This gives us the ability to squash applications of t. Formally, if we have Associative t, we are enriching the category of endofunctors with semigroup structure, turning it into a semigroupoidal category. Different choices of t give different semigroupoidal categories. A functor f is known as a "semigroup in the (semigroupoidal) category of endofunctors on t" if we can biretract:
t f f ~> f
This gives us a few interesting results in category theory, which you can stil reading about if you don't care:
  • All functors are semigroups in the semigroupoidal category on :+:
  • The class of functors that are semigroups in the semigroupoidal category on :*: is exactly the functors that are instances of Alt.
  • The class of functors that are semigroups in the semigroupoidal category on Day is exactly the functors that are instances of Apply.
  • The class of functors that are semigroups in the semigroupoidal category on Comp is exactly the functors that are instances of Bind.
Note that instances of this class are intended to be written with t as a fixed type constructor, and f to be allowed to vary freely:
instance Bind f => SemigroupIn Comp f
Any other sort of instance and it's easy to run into problems with type inference. If you want to write an instance that's "polymorphic" on tensor choice, use the WrapHBF newtype wrapper over a type variable, where the second argument also uses a type constructor:
instance SemigroupIn (WrapHBF t) (MyFunctor t i)
This will prevent problems with overloaded instances.