Skip to content

Instantly share code, notes, and snippets.

@MikuroXina
Created November 5, 2023 23:37
Show Gist options
  • Save MikuroXina/63c3382c903aed7f738866c2c074ae21 to your computer and use it in GitHub Desktop.
Save MikuroXina/63c3382c903aed7f738866c2c074ae21 to your computer and use it in GitHub Desktop.
Monoid implementation of alternating sum with Rust.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct AltSum {
sum: i64,
len: usize,
}
impl AltSum {
pub fn empty() -> Self {
Self { sum: 0, len: 0 }
}
pub fn one(item: i64) -> Self {
Self { sum: item, len: 1 }
}
pub fn sum(self) -> i64 {
self.sum
}
pub fn len(self) -> usize {
self.len
}
}
impl Default for AltSum {
fn default() -> Self {
Self::empty()
}
}
impl Monoid for AltSum {
const ID: Self = Self { sum: 0, len: 0 };
fn op(self, other: Self) -> Self {
Self {
sum: self.sum
+ if self.len % 2 == 0 {
other.sum
} else {
-other.sum
},
len: self.len + other.len,
}
}
}
/// Monoid must satisfy:
/// ```rs
/// fn test<M: Monoid>(m: M, n: M, l: M) {
/// assert_eq!(m.op(M::ID), m);
/// assert_eq!(M::ID.op(m), m);
/// assert_eq!(m.op(n.op(l)), m.op(n).op(l));
/// }
/// ```
pub trait Monoid: Copy + Eq {
const ID: Self;
fn op(self, other: Self) -> Self;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment