80 lines
2.4 KiB
Rust
80 lines
2.4 KiB
Rust
use super::tests::*;
|
|
use super::*;
|
|
|
|
pub trait FunctorTestSuite<'a>: WeakFunctor<'a> + Eqr<'a> {
|
|
fn sample<A: 'a + Send, F: FnMut(&'a (dyn Send + Sync + Fn(A) -> Self::F<A>))>(f: F);
|
|
}
|
|
|
|
pub fn functor_follows_laws<'a, T: Functor<'a> + FunctorTestSuite<'a>>() -> R {
|
|
let mut res = R::default();
|
|
T::sample(|pa| {
|
|
res += fmap_respects_identity::<T, _>(|| pa(2));
|
|
});
|
|
T::sample(|pa| {
|
|
res += fmap_respects_composition::<T, _, _, _>(|x| x + 5, |x| x + 3, || pa(2));
|
|
});
|
|
res
|
|
}
|
|
|
|
pub fn applicative_follows_laws<'a, T: Applicative<'a> + FunctorTestSuite<'a>>() -> R {
|
|
let mut res = functor_follows_laws::<T>();
|
|
T::sample(|pa| {
|
|
res += seq_respects_identity::<T, _>(|| pa(2));
|
|
});
|
|
T::sample(|pa| {
|
|
T::sample(|pg| {
|
|
T::sample(|pf| {
|
|
res += seq_respects_composition::<T, _, _, _, _, _>(
|
|
|| pf(|x| x + 5),
|
|
|| pg(|x| x + 3),
|
|
|| pa(2),
|
|
);
|
|
})
|
|
})
|
|
});
|
|
res += seq_is_homomorphic::<T, _, _>(|x| x + 3, || 2);
|
|
T::sample(|pf| {
|
|
res += seq_respects_interchange::<T, _, _, _>(|| pf(|x| x + 3), || 2);
|
|
});
|
|
T::sample(|pa| {
|
|
T::sample(|pf| {
|
|
res += seq_can_be_expressed_via_la2::<T, _, _, _>(|| pf(|x| x + 3), || pa(2));
|
|
})
|
|
});
|
|
T::sample(|pa| {
|
|
res += fmap_can_be_expressed_via_seq::<T, _, _>(|x| x + 3, || pa(2));
|
|
});
|
|
T::sample(|pa| {
|
|
T::sample(|pb| {
|
|
res += discard_can_be_expressed_via_seq_or_la2::<T, _, _>(|| pa(2), || pb(2));
|
|
})
|
|
});
|
|
res
|
|
}
|
|
|
|
pub fn monad_follows_laws<'a, T: Monad<'a> + FunctorTestSuite<'a>>() -> R {
|
|
let mut res = applicative_follows_laws::<T>();
|
|
T::sample(|pa| {
|
|
res += bind_respects_left_identity::<T, _, _>(|x| pa(x + 3), || 2);
|
|
});
|
|
T::sample(|pa| {
|
|
res += bind_respects_right_identity::<T, _>(|| pa(2));
|
|
});
|
|
T::sample(|pa| {
|
|
T::sample(|pg| {
|
|
T::sample(|pf| {
|
|
res += bind_is_associative::<T, _, _, _>(|x| pf(x + 5), |x| pg(x + 3), || pa(2));
|
|
})
|
|
})
|
|
});
|
|
T::sample(|pa| {
|
|
T::sample(|pf| {
|
|
seq_can_be_expressed_via_bind::<T, _, _, _>(|| pf(|x| x + 3), || pa(2));
|
|
})
|
|
});
|
|
T::sample(|pa| {
|
|
res += fmap_can_be_expressed_via_bind::<T, _, _>(|x| x + 3, || pa(2));
|
|
});
|
|
res
|
|
}
|