Skip to content

Instantly share code, notes, and snippets.

@snoyberg
Created February 8, 2023 16:20
Show Gist options
  • Save snoyberg/1464b2e5c883e8415296c2df82446c74 to your computer and use it in GitHub Desktop.
Save snoyberg/1464b2e5c883e8415296c2df82446c74 to your computer and use it in GitHub Desktop.
Rusty Monoid
#![feature(try_trait_v2)]
use std::ops::Try;
trait Monoid: Default {
fn mappend(self, rhs: Self) -> Self;
}
impl Monoid for i32 {
fn mappend(self, rhs: Self) -> Self {
self + rhs
}
}
trait IteratorExt: Iterator {
fn try_for_each_monoid<F, C, R>(&mut self, f: F) -> R
where
F: Fn(Self::Item) -> R,
C: Monoid,
R: Try<Output = C>,
{
let mut ret = C::default();
for x in self {
let c = f(x)?;
ret = ret.mappend(c);
}
Try::from_output(ret)
}
}
impl<I> IteratorExt for I where I: Iterator {}
fn main() {
let x = (1..=5).try_for_each_monoid(|x| {
if x == 3 {
None
} else {
println!("x == {}", x);
Some(x)
}
});
println!("{x:?}");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment