aboutsummaryrefslogtreecommitdiff
path: root/tests/trivial_lifetime.rs
blob: 04d2d4a6dae397c55d89c0ade484d42ac1bd635f (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
38
39
40
41
42
43
44
#![deny(clippy::pedantic)]
#![deny(clippy::all)]
//! Tests if a trivial functor, which's lifetime depends on the mapping function, works.
use higher::{Bind, Functor};
use higher_free_macro::free;
use std::rc::Rc;

#[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(i32::unsigned_abs),
    });
    let f = f.bind(FreeTriv::Pure);
    match f {
        FreeTriv::Free(f) => {
            let n = (f.next)(-4);
            match n {
                FreeTriv::Pure(v) => assert_eq!(v, 4u32),
                FreeTriv::Free(_) => unreachable!(),
            }
        }
        FreeTriv::Pure(_) => unreachable!(),
    }
}