pub trait EnrichedCategory<V> {
type Hom<A, B>;
fn compose<A: 'static, B: 'static, C: 'static>(
f: Self::Hom<A, B>,
g: Self::Hom<B, C>,
) -> Self::Hom<A, C>;
fn id<A: 'static>() -> Self::Hom<A, A>;
}
pub struct SetEnrichment;
#[cfg(any(feature = "std", feature = "alloc"))]
pub struct SetCategory;
#[cfg(any(feature = "std", feature = "alloc"))]
impl EnrichedCategory<SetEnrichment> for SetCategory {
type Hom<A, B> = Box<dyn Fn(A) -> B>;
fn compose<A: 'static, B: 'static, C: 'static>(
f: Self::Hom<A, B>,
g: Self::Hom<B, C>,
) -> Self::Hom<A, C> {
Box::new(move |a| g(f(a)))
}
fn id<A: 'static>() -> Self::Hom<A, A> {
Box::new(|a| a)
}
}
pub struct MonoidEnrichment;
pub struct MonoidCategory;
impl EnrichedCategory<MonoidEnrichment> for MonoidCategory {
type Hom<A, B> = ();
fn compose<A: 'static, B: 'static, C: 'static>(
_f: Self::Hom<A, B>,
_g: Self::Hom<B, C>,
) -> Self::Hom<A, C> {
}
fn id<A: 'static>() -> Self::Hom<A, A> {}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn set_enriched_compose_chains_functions() {
let f: Box<dyn Fn(i32) -> i32> = Box::new(|x| x + 1);
let g: Box<dyn Fn(i32) -> i32> = Box::new(|x| x * 2);
let gf = SetCategory::compose(f, g);
assert_eq!(gf(5), 12); }
#[test]
fn set_enriched_id_is_identity() {
let id = SetCategory::id::<i32>();
assert_eq!(id(42), 42);
}
}