diff options
| author | Andreas Grois <andi@grois.info> | 2023-03-21 00:10:48 +0100 |
|---|---|---|
| committer | Andreas Grois <andi@grois.info> | 2023-03-21 00:10:48 +0100 |
| commit | e9d126e7ead84fc5319252717d70ce5954aa8526 (patch) | |
| tree | 0672a0119c61f2f350d77b84d2a5d7fe7c96cc4f /tests | |
| parent | 22154f14dd11f45230491cf0e93038ccfee8c85a (diff) | |
Multiple generic parameters now with lifetimes.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/multiple_generics.rs | 21 | ||||
| -rw-r--r-- | tests/multiple_generics_lifetime.rs | 81 |
2 files changed, 102 insertions, 0 deletions
diff --git a/tests/multiple_generics.rs b/tests/multiple_generics.rs index ce13414..2f560dd 100644 --- a/tests/multiple_generics.rs +++ b/tests/multiple_generics.rs @@ -62,4 +62,25 @@ fn test_multiple_generics2(){ }, _ => unreachable!() } +} + +#[test] +fn test_multiple_generics3(){ + let m : FreeResult<_, String> = FreeResult::lift_f(Ok(37u32)); + let f : FreeResult<_, String> = FreeResult::Pure(|x : u32| -> f32 {(x as f32)*0.5f32}).fmap(Into::into); + let m = m.apply(f); + match m{ + FreeResult::Free(m) => { + match &*m{ + Ok(k) => { + match k { + FreeResult::Pure(k) => assert_eq!(18.5f32, *k), + FreeResult::Free(_) => unreachable!(), + } + } + Err(_) => unreachable!(), + } + }, + _ => unreachable!() + } }
\ No newline at end of file diff --git a/tests/multiple_generics_lifetime.rs b/tests/multiple_generics_lifetime.rs new file mode 100644 index 0000000..ddc0628 --- /dev/null +++ b/tests/multiple_generics_lifetime.rs @@ -0,0 +1,81 @@ +//! Tests if multiple generic parameters work, if the return value's lifetime depends on the mapping function lifetime. + +use std::rc::Rc; +use higher_free_macro::free; +use higher::{Functor, Bind, Apply}; + +#[derive(Clone)] +struct TestFunctor<'a, 'b, A, B>{ + data : &'b B, + next : Rc<dyn Fn(i32)->A + 'a>, +} + +impl<'a,'b,A : 'a,B> Functor<'a,A> for TestFunctor<'a, 'b, A, B>{ + type Target<T> = TestFunctor<'a, 'b, T, B>; + + fn fmap<C, F>(self, f: F) -> Self::Target<C> + where + F: Fn(A) -> C + 'a { + TestFunctor{ data : self.data, next : Rc::new(move |x| f((self.next)(x)))} + } +} + +free!(<'xx>, FreeTest<'xx,'yy,AA,BB>, TestFunctor<'xx, 'yy, FreeTest<'xx, 'yy, AA, BB>, BB>); + +#[test] +fn test_lifetime_multiple_generics(){ + let m = FreeTest::lift_f(TestFunctor{ data : &"Listening to NSP while writing this.", next : Rc::new(|x| (x as f32)*0.5f32)}); + let f = FreeTest::Pure(|x : f32| -> bool {x > 0.7f32} ).fmap(Into::into); + let m = m.apply(f); + match m { + FreeTest::Free(m) => { + assert_eq!(m.data, &"Listening to NSP while writing this."); + let x = m.next.clone(); + let y = m.next.clone(); + let m1 = x(1); + match m1{ + FreeTest::Pure(v) => assert!(!v), + FreeTest::Free(_) => unreachable!(), + } + let m2 = y(3); + match m2{ + FreeTest::Pure(v) => assert!(v), + FreeTest::Free(_) => unreachable!(), + } + }, + _ => unreachable!() + } +} + +#[test] +fn test_lifetime_multiple_generics_bind(){ + let m = FreeTest::lift_f(TestFunctor{ data : &"Listening to Soilwork while writing this.", next : Rc::new(|x| (x as f32)*0.5f32)}); + let m = m.bind(|x : f32| -> FreeTest<_,_> { + if x < 0.0 { + FreeTest::Pure(x.abs().floor() as u32) + } else { + FreeTest::lift_f(TestFunctor{data : &"Now it's Little Big.", next : Rc::new(move |y| (y as u32) + (x.ceil() as u32))}) + }}); + match m{ + FreeTest::Free(m) => { + assert_eq!(m.data, &"Listening to Soilwork while writing this."); + match (m.next)(-3){ + FreeTest::Pure(v) => assert_eq!(v, 1), + FreeTest::Free(_) => unreachable!(), + } + match (m.next)(3){ + FreeTest::Pure(_) => unreachable!(), + FreeTest::Free(v) => { + assert_eq!(v.data, &"Now it's Little Big."); + match (v.next)(5) { + FreeTest::Pure(v) => { + assert_eq!(v, 7) + }, + FreeTest::Free(_) => unreachable!(), + } + }, + } + }, + _ => unreachable!() + } +}
\ No newline at end of file |
