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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
#![deny(clippy::pedantic)]
#![deny(clippy::all)]
//! Test for the case that the Functor the Free Monad is based on has lifetime parameters that do not depend on the
//! lifetime of the mapping function in the Functor implementation.
use higher::{Apply, Bind, Functor};
use higher_free_macro::free;
#[derive(Functor, Clone)]
struct WithLifetimes<'a, 'b, A> {
s1: &'a str,
s2: &'b str,
next: A,
}
free!(
FreeWithLifetimes<'a, 'b, A>,
WithLifetimes<'a, 'b, FreeWithLifetimes<'a, 'b, A>>
);
fn lifetime_helper<'a, 'b>(s1: &'a str, s2: &'b str) -> FreeWithLifetimes<'a, 'b, u32> {
let fv = FreeWithLifetimes::lift_f(WithLifetimes { s1, s2, next: 15 });
fv.fmap(|x| x + 1)
}
#[test]
fn test_with_lifetimes() {
let s1 = "First";
let s2 = "Second";
let fv = lifetime_helper(s1, s2);
let s3 = "Third";
let s4 = "Fourth";
let fv = fv.bind(|x| {
FreeWithLifetimes::lift_f(WithLifetimes {
s1: s3,
s2: s4,
next: x + 2,
})
});
let s5 = "Fifth";
let s6 = "Sixth";
let fa = FreeWithLifetimes::lift_f(WithLifetimes {
s1: s5,
s2: s6,
next: (|x| x + 3).into(),
});
let fv = fv.apply(fa);
match fv {
FreeWithLifetimes::Free(v) => {
assert_eq!(v.s1, s5);
assert_eq!(v.s2, s6);
match v.next {
FreeWithLifetimes::Free(v) => {
assert_eq!(v.s1, s1);
assert_eq!(v.s2, s2);
match v.next {
FreeWithLifetimes::Free(v) => {
assert_eq!(v.s1, s3);
assert_eq!(v.s2, s4);
match v.next {
FreeWithLifetimes::Free(_) => unreachable!(),
FreeWithLifetimes::Pure(a) => {
assert_eq!(a, 21);
}
}
}
FreeWithLifetimes::Pure(_) => unreachable!(),
}
}
FreeWithLifetimes::Pure(_) => unreachable!(),
}
}
FreeWithLifetimes::Pure(_) => unreachable!(),
}
}
|