#![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!(), } }