pub trait SemigroupHom {
type Source: Semigroup;
type Target: Semigroup;
// Required method
fn apply(&self, x: &Self::Source) -> Self::Target;
}Expand description
A semigroup homomorphism: a structure-preserving map between semigroups.
A homomorphism f: S → T preserves the semigroup operation:
Laws (not enforced by type system):
- Preserve combine:
f(x.combine(y)) == f(x).combine(f(y))
§Example
use algebra_core::{Semigroup, Monoid, SemigroupHom};
// Wrapper for usize with addition
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct Sum(usize);
impl Semigroup for Sum {
fn combine(&self, other: &Self) -> Self {
Sum(self.0 + other.0)
}
}
impl Monoid for Sum {
fn empty() -> Self { Sum(0) }
}
// String length is a homomorphism from (String, concat) to (Sum, +)
struct Length;
impl SemigroupHom for Length {
type Source = String;
type Target = Sum;
fn apply(&self, s: &String) -> Sum {
Sum(s.len())
}
}
// Verify: len(s1 + s2) = len(s1) + len(s2)
let len = Length;
let s1 = String::from("hello");
let s2 = String::from("world");
assert_eq!(
len.apply(&s1.clone().combine(&s2)),
len.apply(&s1).combine(&len.apply(&s2))
);