Data.Semigroup
The Semigroup
Semigroup
with an identity value.Packages[edit]
- (base) Data.Semigroup
Syntax[edit]
class Semigroup a where (<>) :: a -> a -> a sconcat :: [[Data.List.Nonempty|Nonempty]] a -> a stimes :: Integral b => b -> a -> a
Minimal Complete Definition[edit]
(<>)
Description[edit]
a
which has an associative binary operation will be able to become a member of the Semigroup
typeclass. An instance of Monoid a
automatically satisfies the requirements of a Semigroup
making Semigroup
a strict superset of Monoid
. The Monoid
typeclass however does not enforce it's instances to already be instances of Semigroup
Semigroup
is a particularly forgiving typeclass in it's requirements, and datatypes may have many instances of Semigroup
as long as they have functions which satisfy the requirements.Semigroup Laws[edit]
In addition to the class requirements above, potential instances of Semigroup
must obey a single law in order to become instances:
- The binary operation
<>
must be associative (a <> b) <> c == a <> (b <> c)
- As long as you do not change the order of the arguments, you can insert parenthesis anywhere, and the result will be the same.
For example, addition (a + (b + c) == (a + b) + c
), and multiplication (a * (b * c) == (a * b) * c
) satisfy this requirement. Therefore <>
could be defined as +
or *
for instances of class Num a
. Division (div
) however, would not be a candidate as it is not associative: 8 `div` (4 `div` 2) == 8 `div` 2 == 4
is not equal to (8 `div` 4) `div` 2 == 2 `div` 2 == 1
.
<>
function could do anything, as long as it doesn't matter where you put parenthesis.Rules for Monoids[edit]
Instances of Monoid
have to obey an additional rule:
(<>) == mappend
This is to ensure that the instance of Monoid
is equivalent to a more strict instance of Semigroup
.
Methods[edit]
(<>) :: a -> a -> a
- An associative binary operation.
sconcat :: [[Data.List.Nonempty|Nonempty]] a -> a
- Take a nonempty list of type
a
and apply the<>
operation to all of them to get a single result.
stimes :: Integral b => b -> a -> a
- Given a number
x
and a value of typea
, combinex
numbers of the valuea
by repeatedly applying<>
.
Examples[edit]
Sum numbers using <>
: [edit]
<>
:Sum 3 <> Sum 4 -- with the type "Sum a", "<>" becomes "+" -- returns: Sum {getSum = 7} because (3 <> 4) == (3 + 4) == 7
Exponents using stimes
: [edit]
stimes
:stimes 4 (Product 3) -- with the type "Product a" "<>" becomes "*" -- returns: Product {getProduct = 81} -- This is because (3 <> 3 <> 3 <> 3) == (3 * 3 * 3 * 3) == 81 -- i.e. 4 copies of 3 combined via multiplication.
Test for any elements which are True in a non-empty list using sconcat
: [edit]
sconcat
:sconcat (Any True :| [Any False, Any True, Any False]) -- sconcat will apply "<>" to all of the members in a list -- returns: Any {getAny = True} -- If any elements in the list are True than the whole expression is True -- The type "Any" converts "<>" to "||" -- (True <> False <> True <> False) == (True || False || True || False) == True
Test if all elements are True in a non-empty list using sconcat
: [edit]
sconcat
:sconcat (All True :| [All False, All True, All False]) -- returns: All {getAll = False} -- If all elements in the list are True than the whole expression is True -- The type "All" converts "<>" to "&&" -- (True <> False <> True <> False) == (True && False && True && False) == True
See Also[edit]
- Data.Monoid: a special case of
Semigroup
with an identity elementmempty