use super::Monoid;
pub trait MonoidAction<M: Monoid, T> {
fn act(monoid: M, target: T) -> T;
fn preview_act(monoid: &M, target: &T) -> T
where
M: Clone,
T: Clone,
{
Self::act(monoid.clone(), target.clone())
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::BTreeSet;
struct SetAddAction;
impl<T: Ord + Clone> MonoidAction<BTreeSet<T>, BTreeSet<T>> for SetAddAction {
fn act(monoid: BTreeSet<T>, target: BTreeSet<T>) -> BTreeSet<T> {
target.union(&monoid).cloned().collect()
}
}
#[test]
fn test_action_identity() {
let target: BTreeSet<i32> = [1, 2, 3].iter().cloned().collect();
let identity = BTreeSet::identity();
let result = SetAddAction::act(identity, target.clone());
assert_eq!(result, target);
}
#[test]
fn test_action_compatibility() {
use crate::algebra::Semigroup;
let m1: BTreeSet<i32> = [4, 5].iter().cloned().collect();
let m2: BTreeSet<i32> = [6, 7].iter().cloned().collect();
let target: BTreeSet<i32> = [1, 2, 3].iter().cloned().collect();
let left = SetAddAction::act(m1.clone().combine(m2.clone()), target.clone());
let right = SetAddAction::act(m1, SetAddAction::act(m2, target));
assert_eq!(left, right);
}
#[test]
fn test_preview_act() {
let monoid: BTreeSet<i32> = [4, 5].iter().cloned().collect();
let target: BTreeSet<i32> = [1, 2, 3].iter().cloned().collect();
let result = SetAddAction::preview_act(&monoid, &target);
assert_eq!(target, [1, 2, 3].iter().cloned().collect());
assert_eq!(result, [1, 2, 3, 4, 5].iter().cloned().collect());
}
}