use crate::prelude::Applicative;
use super::Cont;
impl<'a, R, A> Applicative<'a, A> for Cont<'a, R, A>
where
R: 'a,
A: 'a,
{
type PureT<T> = T where T: 'a;
fn pure(a: Self::PureT<A>) -> Self::Type<Self::PureT<A>> {
Self::Type::<Self::PureT<A>> {
run_cont: Box::new(|f| f(a)),
}
}
fn app<F, B>(self, f: Self::Type<F>) -> Self::Type<B>
where
F: Fn(A) -> B + 'a,
B: 'a,
{
let brr = move |br: Box<dyn FnOnce(B) -> R + 'a>| -> R {
let abr = move |f: F| -> R {
let ar = move |a: A| -> R {
let b = f(a);
br(b)
};
let arr = self.run_cont;
arr(Box::new(ar))
};
let abrr = f.run_cont;
abrr(Box::new(abr))
};
Self::Type::<B> {
run_cont: Box::new(brr),
}
}
}