use crate::function::{CFnOnce, RcFn};
use std::rc::Rc;
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 RcFn<X, A> {
type Functor<T> = RcFn<X, T>;
fn map<B, Func>(self, func: Func) -> RcFn<X, B>
where
Func: FnMut(A) -> B + Clone + 'static,
{
let inner = self.0.clone();
RcFn(Rc::new(move |x: X| func.clone()(inner(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)))
}
}