定義済み演算
seg_lib
を利用するたびにMonoid
トレイトなどを実装するのは面倒です。
そこで、典型的なモノイドのテンプレートを用意しました。
一覧はドキュメントから確認できます。
モノイドのテンプレート
#![allow(unused)] fn main() { #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Add<T>(PhantomData<T>); impl<T> Monoid for Add<T> where T: Zero, for<'a> &'a T: std::ops::Add<Output = T>, { type Set = T; const IS_COMMUTATIVE: bool = true; fn identity() -> Self::Set { T::zero() } fn combine(lhs_or_prev: &Self::Set, rhs_or_new: &Self::Set) -> Self::Set { lhs_or_prev + rhs_or_new } } }
例えば、Add<i32>
はモノイド(i32, +, 0)
に対応します。
トレイト境界のとり方には他にもいくつかのパターンが考えられます。
T: Copy + Zero + std::ops::Add<Output = T>
T: Clone + Zero + std::ops::Add<Output = T>
これらは、combine()
の挙動に影響を与えます。
最適な実装は型に依るため、ユーザーに定義してもらうことにしました。
モノイド作用について
現在の実装では関連型にモノイドのテンプレートを利用することはできますが、act()
はユーザーが定義することになっています。