use hkt::*;
use super::functor::Functor;
pub trait Applicative: Functor {
fn ap<Y, U>(self, rhs: rebind1!(Self, Y)) -> rebind1!(Self, U)
where Y: Clone,
Self: Sized,
Self::Unit: Rebind1<Y>,
Self::Unit: Rebind1<U>,
rebind1!(Self, Y): Applicative,
rebind1!(Self, U): Applicative,
generic1!(Self): Fn(Y) -> U;
fn unit(value: generic1!(Self)) -> Self;
}
impl<T> Applicative for Option<T>
where T: Same<Type = <Option<T> as Generic1>::Type>
{
fn ap<Y, U>(self, rhs: rebind1!(Self, Y)) -> rebind1!(Self, U)
where generic1!(Self): Fn(Y) -> U
{
match self {
Some(f) => rhs.fmap(f),
None => None
}
}
fn unit(value: generic1!(Self)) -> Self { Some(value) }
}
impl<T, E> Applicative for Result<T, E>
where T: Same<Type = <Result<T, E> as Generic1>::Type>
{
fn ap<Y, U>(self, rhs: rebind1!(Self, Y)) -> rebind1!(Self, U)
where generic1!(Self): Fn(Y) -> U
{
match self {
Ok(f) => rhs.fmap(f),
Err(err) => Err(err)
}
}
fn unit(value: generic1!(Self)) -> Self { Ok(value) }
}
impl<T> Applicative for Vec<T> {
fn ap<Y, U>(self, rhs: rebind1!(Self, Y)) -> rebind1!(Self, U)
where Y: Clone, generic1!(Self): Fn(Y) -> U
{
self.into_iter().flat_map(|f| rhs.iter().map(move |x| f(x.clone()))).collect()
}
fn unit(value: generic1!(Self)) -> Self { vec![value] }
}