Semigroups and monoids are algebraic structures that provide a way to combine values. Phunkie implements these concepts to enable consistent and predictable value composition.
A semigroup is a type that can be combined with another value of the same type using an associative operation.
Phunkie provides a combine
function that works with various types:
use function Phunkie\Functions\semigroup\combine;
// Numbers
combine(1, 2); // 3
combine(1.5, 2.5); // 4.0
// Strings
combine("Hello ", "World"); // "Hello World"
// Booleans
combine(true, false); // false (logical AND)
// Arrays
combine([1, 2], [3, 4]); // [1, 2, 3, 4]
// Multiple values
combine(1, 2, 3, 4); // 10
The combine operation must satisfy the associative law:
combine(combine($a, $b), $c) === combine($a, combine($b, $c))
A monoid extends the semigroup concept by adding an identity element (zero). In Phunkie, this is implemented through the zero
function.
use function Phunkie\Functions\semigroup\zero;
zero(0); // 0
zero(0.0); // 0.0
zero(""); // ""
zero(true); // true
zero([]); // []
Monoids must satisfy three laws:
combine(zero($a), $a) === $a
combine($a, zero($a)) === $a
combine(combine($a, $b), $c) === combine($a, combine($b, $c))
ImmLists form a monoid under concatenation:
use Phunkie\Types\ImmList;
$list1 = ImmList(1, 2);
$list2 = ImmList(3, 4);
// Zero
$list1->zero(); // Nil()
// Combine
$list1->combine($list2); // ImmList(1, 2, 3, 4)
Options form a monoid when their contents can be combined:
use Phunkie\Types\Option;
$opt1 = Some(1);
$opt2 = Some(2);
$none = None();
// Zero
$opt1->zero(); // None()
// Combine
$opt1->combine($opt2); // Some(3)
$opt1->combine($none); // Some(1)
$none->combine($opt1); // Some(1)
To make your type a semigroup, implement the combine method:
class MyType {
public function combine($other): self {
// Implement combining logic here
return new self(/* combined result */);
}
}
To make it a monoid, also implement the zero method:
class MyType {
public function zero() {
// Return identity element
return new self(/* identity value */);
}
public function combine($other): self {
// Implement combining logic here
}
}
combine()
for consistent value compositionzero()
when you need an identity elementMonoidLaws
and SemigroupLaws
traitscombine
function handles type checking and dispatchingcombine
and zero
methods