use crate::function::{CFn, CFnOnce};
pub trait Functor<A> {
type Functor<T>;
fn map<B, Func>(self, f: Func) -> <Self as Functor<A>>::Functor<B>
where
Func: Fn(A) -> B + Clone + 'static;
}
impl<A: 'static> Functor<A> for Option<A> {
type Functor<T> = Option<T>;
fn map<B, Func>(self, f: Func) -> <Self as Functor<A>>::Functor<B>
where
Func: FnMut(A) -> B + 'static,
{
self.map(f)
}
}
impl<A: 'static, E: 'static> Functor<A> for Result<A, E> {
type Functor<T> = Result<T, E>;
fn map<B, Func>(self, f: Func) -> <Self as Functor<A>>::Functor<B>
where
Func: FnMut(A) -> B + 'static,
{
self.map(f)
}
}
impl<A: 'static> Functor<A> for Vec<A> {
type Functor<T> = Vec<T>;
fn map<B, Func>(self, f: Func) -> <Self as Functor<A>>::Functor<B>
where
Func: FnMut(A) -> B + 'static,
{
self.into_iter().map(f).collect()
}
}
impl<X: 'static, A: 'static> Functor<A> for CFn<X, A> {
type Functor<T> = CFnOnce<X, T>;
fn map<B, Func>(self, mut f: Func) -> Self::Functor<B>
where
Func: FnMut(A) -> B + 'static,
{
CFnOnce::new(move |x: X| f(self.call(x)))
}
}
impl<X: 'static, A: 'static> Functor<A> for CFnOnce<X, A> {
type Functor<T> = CFnOnce<X, T>;
fn map<B, Func>(self, mut f: Func) -> Self::Functor<B>
where
Func: FnMut(A) -> B + 'static,
{
CFnOnce::new(move |x: X| f(self.call_once(x)))
}
}