use super::Semigroup;
use std::collections::BTreeSet;
pub trait Monoid: Semigroup {
fn identity() -> Self;
fn combine_all_with_identity<I: IntoIterator<Item = Self>>(iter: I) -> Self {
Self::combine_all(iter).unwrap_or_else(Self::identity)
}
}
impl<T: Ord + Clone> Monoid for BTreeSet<T> {
#[inline]
fn identity() -> Self {
BTreeSet::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::algebra::Semigroup;
#[test]
fn test_btreeset_left_identity() {
let a: BTreeSet<i32> = [1, 2, 3].iter().cloned().collect();
let e = BTreeSet::identity();
assert_eq!(e.combine(a.clone()), a);
}
#[test]
fn test_btreeset_right_identity() {
let a: BTreeSet<i32> = [1, 2, 3].iter().cloned().collect();
let e = BTreeSet::identity();
assert_eq!(a.clone().combine(e), a);
}
#[test]
fn test_combine_all_with_identity_empty() {
let empty: Vec<BTreeSet<i32>> = vec![];
let result = BTreeSet::combine_all_with_identity(empty);
assert_eq!(result, BTreeSet::identity());
}
#[test]
fn test_combine_all_with_identity_nonempty() {
let sets = vec![
[1, 2].iter().cloned().collect::<BTreeSet<_>>(),
[3, 4].iter().cloned().collect::<BTreeSet<_>>(),
];
let result = BTreeSet::combine_all_with_identity(sets);
assert_eq!(result, [1, 2, 3, 4].iter().cloned().collect());
}
}