use crate::traits::{Applicative, Monoid};
use super::Writer;
impl<'a, W, A> Applicative<'a, A> for Writer<'a, W, A>
where
W: Monoid + 'a,
A: 'a,
{
type PureT<T> = T where T: 'a;
fn pure(a: Self::PureT<A>) -> Self::Type<Self::PureT<A>> {
Writer::<'a, W, Self::PureT<A>> {
run_writer: Some(Box::new(|w| (a, w))),
}
}
fn app<F, B>(self, writer_f: Self::Type<F>) -> Self::Type<B>
where
F: Fn(A) -> B + 'a,
B: 'a,
{
Self::Type::<B> {
run_writer: Some(Box::new(move |w: W| -> (B, W) {
let (f, wf) = writer_f.run_with(w);
let (a, wt) = self.run_with(wf);
(f(a), wt)
})),
}
}
}