#![deny(clippy::pedantic)] #![deny(clippy::all)] //! Tests if multiple generic parameters work, for the case that lifetimes are independent of mapping functions. //! For simplicity, it just creates a `FreeResult` based on `Result`. use higher::{Apply, Bind, Functor}; use higher_free_macro::free; free!(FreeResult, Result,E>); //just to appease clippy without disabling the lint.... macro_rules! assert_nearly_equal { ($a:expr, $b:expr, $c:expr) => { assert!((($a) - ($b)).abs() < $c) }; } #[test] fn test_multiple_generics() { let m: FreeResult<_, String> = FreeResult::lift_f(Ok(37u32)); let m = m.fmap(|x| x * 2); let m = m.bind(|x| FreeResult::Free(Box::new(Ok(FreeResult::Pure(x))))); let f = FreeResult::Pure((|x| x * 3).into()); let m = m.apply(f); match m { FreeResult::Free(b) => match *b { Ok(FreeResult::Free(b)) => match *b { Ok(FreeResult::Pure(x)) => assert_eq!(x, 37 * 6), _ => unreachable!(), }, _ => unreachable!(), }, FreeResult::Pure(_) => unreachable!(), } } #[test] fn test_multiple_generics2() { let m: FreeResult<_, String> = FreeResult::lift_f(Ok(37u32)); let m = m.bind(|_| FreeResult::::lift_f(Err("An early out.".to_owned()))); match m { FreeResult::Free(m) => match &*m { Ok(FreeResult::Free(m)) => match &**m { Err(e) => assert_eq!(e, "An early out."), _ => unreachable!(), }, _ => unreachable!(), }, FreeResult::Pure(_) => unreachable!(), } } #[test] fn test_multiple_generics3() { let m: FreeResult<_, String> = FreeResult::lift_f(Ok(37u32)); let f: FreeResult<_, String> = FreeResult::Pure(|x: u32| -> f64 { f64::from(x) * 0.5f64 }).fmap(Into::into); let m = m.apply(f); match m { FreeResult::Free(m) => match &*m { Ok(k) => match k { FreeResult::Pure(k) => assert_nearly_equal!(18.5f64, *k, f64::EPSILON), FreeResult::Free(_) => unreachable!(), }, Err(_) => unreachable!(), }, FreeResult::Pure(_) => unreachable!(), } }