use lift::{Higher, Functor};
use std::hash::Hash;
use std::collections::linked_list::LinkedList;
use std::collections::vec_deque::VecDeque;
use std::collections::{BinaryHeap, BTreeSet, HashSet};
impl<A, B> Functor<A> for Option<B> {
fn fmap<F>(&self, f: F) -> Option<A>
where F: Fn(&B) -> A
{
match *self {
Some(ref x) => Some(f(x)),
None => None,
}
}
}
impl<A, B> Functor<A> for Box<B> {
fn fmap<F>(&self, f: F) -> Box<A>
where F: Fn(&B) -> A
{
Box::new(f(self))
}
}
impl<A: Ord, B: Ord> Functor<A> for BinaryHeap<B> {
fn fmap<F>(&self, f: F) -> BinaryHeap<A>
where F: Fn(&B) -> A
{
self.iter().map(f).collect::<BinaryHeap<A>>()
}
}
impl<A: Ord, B: Ord> Functor<A> for BTreeSet<B> {
fn fmap<F>(&self, f: F) -> BTreeSet<A>
where F: Fn(&B) -> A
{
self.iter().map(f).collect::<BTreeSet<A>>()
}
}
impl<A: Eq + Hash, B: Eq + Hash> Functor<A> for HashSet<B> {
fn fmap<F>(&self, f: F) -> HashSet<A>
where F: Fn(&B) -> A
{
self.iter().map(f).collect::<HashSet<A>>()
}
}
functorize!(LinkedList);
functorize!(Vec);
functorize!(VecDeque);
#[cfg(test)]
mod test {
use lift::Functor;
#[test]
fn test_option() {
assert_eq!(Some(2).fmap(|x| x + 1), Some(3));
}
#[test]
fn test_vec() {
assert_eq!(vec![1, 2, 3].fmap(|x| x * x), vec![1, 4, 9]);
}
#[test]
fn test_box() {
assert_eq!(Box::new(1).fmap(|x| x + 1), Box::new(2));
}
}