aboutsummaryrefslogtreecommitdiff
path: root/tests/trivial_lifetime.rs
blob: fe0523417c024ae1c822fcece276f340836837eb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//! Tests if a trivial functor, which's lifetime depends on the mapping function, works.
use std::rc::Rc;
use higher::{Functor, Bind};
use higher_free_macro::free;

#[derive(Clone)]
struct TrivWithLifetime<'a,A,B>{
    next : Rc<dyn Fn(B)->A + 'a>,
}

impl<'a,A : 'a,B : 'a> Functor<'a,A> for TrivWithLifetime<'a,A,B> {
    type Target<T> = TrivWithLifetime<'a,T,B>;

    fn fmap<C, F>(self, f: F) -> Self::Target<C>
    where
        F: Fn(A) -> C + 'a {
        TrivWithLifetime{ next : Rc::new(move |x| f((self.next)(x)))}
    }
}

free!(<'a>, FreeTriv<'a,A,B>, TrivWithLifetime<'a,FreeTriv<'a,A,B>,B>);

#[test]
fn test_trivial_with_lifetime(){
    let f = FreeTriv::lift_f(TrivWithLifetime{next : Rc::new(|x : i32| x.abs() as u32)});
    let f = f.bind(|x| FreeTriv::Pure(x));
    match f {
        FreeTriv::Free(f) => {
            let n = (f.next)(-4);
            match n {
                FreeTriv::Pure(v) => assert_eq!(v,4u32),
                FreeTriv::Free(_) => unreachable!(),
            }
        },
        _ => unreachable!()
    }
}