use {
core::ops::ControlFlow,
fp_library::{
brands::{
LazyBrand,
RcFnBrand,
ThunkBrand,
},
classes::{
foldable::Foldable,
monad_rec::tail_rec_m,
},
dispatch::functor::explicit::map,
types::{
Lazy,
RcLazyConfig,
Thunk,
},
},
};
#[test]
fn test_eval_monad_rec() {
fn factorial(n: u64) -> Thunk<'static, u64> {
tail_rec_m::<ThunkBrand, _, _>(
|(n, acc)| {
if n == 0 {
Thunk::pure(ControlFlow::Break(acc))
} else {
Thunk::pure(ControlFlow::Continue((n - 1, n * acc)))
}
},
(n, 1),
)
}
assert_eq!(factorial(5).evaluate(), 120);
}
#[test]
fn test_eval_foldable() {
let res_right = ThunkBrand::fold_right::<RcFnBrand, _, _>(|a, b| a + b, 5, Thunk::pure(10));
assert_eq!(res_right, 15);
let res_left = ThunkBrand::fold_left::<RcFnBrand, _, _>(|b, a| b + a, 5, Thunk::pure(10));
assert_eq!(res_left, 15);
}
#[test]
fn test_memo_ref_functor() {
let memo = Lazy::<_, RcLazyConfig>::new(|| 10);
let mapped = map::<LazyBrand<RcLazyConfig>, _, _, _, _>(|x: &i32| *x * 2, &memo);
assert_eq!(*mapped.evaluate(), 20);
}