functional 0.0.7

Functional traits
use hkt::*;
use super::functor::Functor;

/// A functor with application
pub trait Applicative: Functor {
    /// Apply wrapped function to wrapped value
    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] }    
}