haar_lib/algebra/
first_last.rs

1//! First, Lastモノイド
2use std::marker::PhantomData;
3
4pub use crate::algebra::traits::*;
5use crate::impl_algebra;
6
7/// 最初に出現する`Some`を返す演算。
8#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
9pub struct First<T>(PhantomData<T>);
10/// 最後に出現する`Some`を返す演算。
11#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
12pub struct Last<T>(PhantomData<T>);
13
14impl<T> First<T> {
15    /// [`First<T>`]を返す。
16    pub fn new() -> Self {
17        Self(PhantomData)
18    }
19}
20impl<T> Last<T> {
21    /// [`Last<T>`]を返す。
22    pub fn new() -> Self {
23        Self(PhantomData)
24    }
25}
26
27impl_algebra!({T} First<T>; set: Option<T>; op: |_, a: Option<T>, b| a.or(b);
28    id: |_| None; assoc; idem;);
29impl_algebra!({T} Last<T>; set: Option<T>; op: |_, a, b: Option<T>| b.or(a);
30    id: |_| None; assoc; idem;);
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35
36    #[test]
37    fn test() {
38        let a = [None, None, Some(1), None, Some(3), Some(5)];
39
40        assert_eq!(a.iter().cloned().fold_m(&First::new()), Some(1));
41        assert_eq!(a.iter().cloned().fold_m(&Last::new()), Some(5));
42    }
43}