use crate::{Apply, Semigroup};
pub trait Semigroupoid {
fn compose(self, other: Self) -> Self;
}
#[allow(dead_code)]
pub fn compose<A, B, C, G, F>(f: F, g: G) -> impl Fn(A) -> C
where
F: Fn(A) -> B,
G: Fn(B) -> C,
{
move |x| g(f(x))
}
impl<A> Semigroupoid for Option<A>
where
A: Semigroup + Clone,
{
fn compose(self, other: Self) -> Self {
self.lift_a2(other, |a, b| a.mappend(b))
}
}
#[cfg(test)]
mod tests {
use crate::semigroupoid;
use crate::Semigroup;
use crate::Semigroupoid;
#[test]
fn fun_compose() {
let f = |a: i32| a.to_string();
let g = |a: String| a.mappend("BAR".to_string());
assert_eq!("12BAR".to_string(), semigroupoid::compose(f, g)(12));
}
#[test]
fn option_compose() {
let a = Option::Some(String::from("FOO"));
let b = Option::Some(String::from("BAR"));
assert_eq!("FOOBAR".to_string(), a.compose(b).unwrap());
}
}