simplify WrapFunction
Some checks failed
buildbot/cargo fmt (1.72) Build done.
buildbot/cargo clippy (1.65) Build done.
buildbot/cargo doc (1.72) Build done.
buildbot/cargo clippy (1.72) Build done.
buildbot/cargo test (1.65) Build done.

This commit is contained in:
AF 2023-10-15 17:11:43 +00:00
parent be61a0bf3b
commit 8ee0a196c6
9 changed files with 47 additions and 39 deletions

View File

@ -179,6 +179,8 @@ impl<'a, U: SharedFunctor<'a> + Functor<'a>, V: SharedFunctor<'a>> SharedFunctor
#[cfg(test)] #[cfg(test)]
mod composition_tests { mod composition_tests {
use std::sync::Arc;
use crate::func::instances::{option::OptionInstance, result::ResultInstance}; use crate::func::instances::{option::OptionInstance, result::ResultInstance};
use super::{test_suite, tests, CompositionInstance}; use super::{test_suite, tests, CompositionInstance};
@ -196,14 +198,13 @@ mod composition_tests {
} }
impl<'a> test_suite::FunctorTestSuite<'a> for T { impl<'a> test_suite::FunctorTestSuite<'a> for T {
fn sample<A: 'a + Send, F: FnMut(Box<dyn test_suite::WrapFunction<'a, A, Self::F<A>>>)>( fn sample<A: 'a + Send, F: FnMut(Arc<dyn test_suite::WrapFunction<'a, A, Self::F<A>>>)>(
mut f: F, mut f: F,
) { ) {
OptionInstance::sample(|ua0| { OptionInstance::sample(|ua0| {
ResultInstance::sample(|a0| { ResultInstance::sample(|a0| {
let ua0 = std::sync::Arc::new(ua0.clone_boxed()); let ua0 = ua0.clone();
let a0 = std::sync::Arc::new(a0.clone_boxed()); f(Arc::new(move |a| ua0(a0(a))))
f(Box::new(move |a| ua0(a0(a))))
}) })
}); });
} }

View File

@ -162,6 +162,8 @@ impl<'a, E: 'a + Send> LocalFunctor<'a> for EffectInstance<E> {
#[cfg(test)] #[cfg(test)]
mod effect_tests { mod effect_tests {
use std::sync::Arc;
use super::{test_suite, tests, Effect, EffectInstance, WithEffect}; use super::{test_suite, tests, Effect, EffectInstance, WithEffect};
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@ -232,10 +234,10 @@ mod effect_tests {
} }
impl<'a> test_suite::FunctorTestSuite<'a> for T { impl<'a> test_suite::FunctorTestSuite<'a> for T {
fn sample<A: 'a + Send, F: FnMut(Box<dyn test_suite::WrapFunction<'a, A, Self::F<A>>>)>( fn sample<A: 'a + Send, F: FnMut(Arc<dyn test_suite::WrapFunction<'a, A, Self::F<A>>>)>(
mut f: F, mut f: F,
) { ) {
f(Box::new(|a| WithEffect { f(Arc::new(|a| WithEffect {
value: a, value: a,
effect: TestEffect::Sample, effect: TestEffect::Sample,
})); }));

View File

@ -139,6 +139,8 @@ impl<'a> SharedFunctor<'a> for FutureInstance {
#[cfg(test)] #[cfg(test)]
mod future_tests { mod future_tests {
use std::sync::Arc;
use crate::func::{applicative_select::Selected, tests::Eqr, ApplicativeSelect}; use crate::func::{applicative_select::Selected, tests::Eqr, ApplicativeSelect};
use super::{test_suite, tests, FutureInstance}; use super::{test_suite, tests, FutureInstance};
@ -160,10 +162,10 @@ mod future_tests {
} }
impl<'a> test_suite::FunctorTestSuite<'a> for T { impl<'a> test_suite::FunctorTestSuite<'a> for T {
fn sample<A: 'a + Send, F: FnMut(Box<dyn test_suite::WrapFunction<'a, A, Self::F<A>>>)>( fn sample<A: 'a + Send, F: FnMut(Arc<dyn test_suite::WrapFunction<'a, A, Self::F<A>>>)>(
mut f: F, mut f: F,
) { ) {
f(Box::new(|a| Box::pin(futures::future::ready(a)))); f(Arc::new(|a| Box::pin(futures::future::ready(a))));
} }
} }

View File

@ -105,6 +105,8 @@ impl<'a> Monad<'a> for LazyInstance {
#[cfg(test)] #[cfg(test)]
mod lazy_tests { mod lazy_tests {
use std::sync::Arc;
use super::{test_suite, tests, LazyInstance}; use super::{test_suite, tests, LazyInstance};
type T = LazyInstance; type T = LazyInstance;
@ -120,10 +122,10 @@ mod lazy_tests {
} }
impl<'a> test_suite::FunctorTestSuite<'a> for T { impl<'a> test_suite::FunctorTestSuite<'a> for T {
fn sample<A: 'a + Send, F: FnMut(Box<dyn test_suite::WrapFunction<'a, A, Self::F<A>>>)>( fn sample<A: 'a + Send, F: FnMut(Arc<dyn test_suite::WrapFunction<'a, A, Self::F<A>>>)>(
mut f: F, mut f: F,
) { ) {
f(Box::new(|a| Box::new(|| a))); f(Arc::new(|a| Box::new(|| a)));
} }
} }

View File

@ -134,6 +134,8 @@ impl<'a> Fail<'a, ()> for OptionInstance {
#[cfg(test)] #[cfg(test)]
mod option_tests { mod option_tests {
use std::sync::Arc;
use super::{test_suite, tests, Functor}; use super::{test_suite, tests, Functor};
use super::OptionInstance as T; use super::OptionInstance as T;
@ -149,11 +151,11 @@ mod option_tests {
} }
impl<'a> test_suite::FunctorTestSuite<'a> for T { impl<'a> test_suite::FunctorTestSuite<'a> for T {
fn sample<A: 'a + Send, F: FnMut(Box<dyn test_suite::WrapFunction<'a, A, Self::F<A>>>)>( fn sample<A: 'a + Send, F: FnMut(Arc<dyn test_suite::WrapFunction<'a, A, Self::F<A>>>)>(
mut f: F, mut f: F,
) { ) {
f(Box::new(|_| None)); f(Arc::new(|_| None));
f(Box::new(|a| Some(a))); f(Arc::new(|a| Some(a)));
} }
} }

View File

@ -248,6 +248,8 @@ impl<'a, T: Monad<'a>> MonadFailAny<'a> for ResultFailOver<T> {
#[cfg(test)] #[cfg(test)]
mod result_tests { mod result_tests {
use std::sync::Arc;
use super::{test_suite, tests, ResultInstance}; use super::{test_suite, tests, ResultInstance};
type T = ResultInstance<i32>; type T = ResultInstance<i32>;
@ -263,14 +265,14 @@ mod result_tests {
} }
impl<'a> test_suite::FunctorTestSuite<'a> for T { impl<'a> test_suite::FunctorTestSuite<'a> for T {
fn sample<A: 'a + Send, F: FnMut(Box<dyn test_suite::WrapFunction<'a, A, Self::F<A>>>)>( fn sample<A: 'a + Send, F: FnMut(Arc<dyn test_suite::WrapFunction<'a, A, Self::F<A>>>)>(
mut f: F, mut f: F,
) { ) {
f(Box::new(|_| Err(0))); f(Arc::new(|_| Err(0)));
f(Box::new(|_| Err(1))); f(Arc::new(|_| Err(1)));
f(Box::new(|_| Err(2))); f(Arc::new(|_| Err(2)));
f(Box::new(|_| Err(3))); f(Arc::new(|_| Err(3)));
f(Box::new(|a| Ok(a))); f(Arc::new(|a| Ok(a)));
} }
} }

View File

@ -119,6 +119,8 @@ impl<'a> Fail<'a, std::convert::Infallible> for SoloInstance {
#[cfg(test)] #[cfg(test)]
mod solo_tests { mod solo_tests {
use std::sync::Arc;
use super::{test_suite, tests, SoloInstance}; use super::{test_suite, tests, SoloInstance};
type T = SoloInstance; type T = SoloInstance;
@ -134,10 +136,10 @@ mod solo_tests {
} }
impl<'a> test_suite::FunctorTestSuite<'a> for T { impl<'a> test_suite::FunctorTestSuite<'a> for T {
fn sample<A: 'a + Send, F: FnMut(Box<dyn test_suite::WrapFunction<'a, A, Self::F<A>>>)>( fn sample<A: 'a + Send, F: FnMut(Arc<dyn test_suite::WrapFunction<'a, A, Self::F<A>>>)>(
mut f: F, mut f: F,
) { ) {
f(Box::new(|a| a)); f(Arc::new(|a| a));
} }
} }

View File

@ -262,6 +262,8 @@ impl<'a> Monad<'a> for StacklessInstance {
#[cfg(test)] #[cfg(test)]
mod stackless_test { mod stackless_test {
use std::sync::Arc;
use crate::func::*; use crate::func::*;
use super::{test_suite, tests, Stackless}; use super::{test_suite, tests, Stackless};
@ -279,10 +281,10 @@ mod stackless_test {
} }
impl<'a> test_suite::FunctorTestSuite<'a> for T { impl<'a> test_suite::FunctorTestSuite<'a> for T {
fn sample<A: 'a + Send, F: FnMut(Box<dyn test_suite::WrapFunction<'a, A, Self::F<A>>>)>( fn sample<A: 'a + Send, F: FnMut(Arc<dyn test_suite::WrapFunction<'a, A, Self::F<A>>>)>(
mut f: F, mut f: F,
) { ) {
f(Box::new(|a| a.into())); f(Arc::new(|a| a.into()));
} }
} }

View File

@ -3,18 +3,12 @@ use std::sync::Arc;
use super::tests::*; use super::tests::*;
use super::*; use super::*;
pub trait WrapFunction<'a, A, B>: 'a + Send + Sync + Fn(A) -> B { pub trait WrapFunction<'a, A, B>: 'a + Send + Sync + Fn(A) -> B {}
fn clone_boxed(&self) -> Box<dyn WrapFunction<'a, A, B>>;
}
impl<'a, A, B, F: 'a + Send + Sync + Clone + Fn(A) -> B> WrapFunction<'a, A, B> for F { impl<'a, A, B, F: 'a + Send + Sync + Clone + Fn(A) -> B> WrapFunction<'a, A, B> for F {}
fn clone_boxed(&self) -> Box<dyn WrapFunction<'a, A, B>> {
Box::new(self.clone())
}
}
pub trait FunctorTestSuite<'a>: WeakFunctor<'a> + Eqr<'a> { pub trait FunctorTestSuite<'a>: WeakFunctor<'a> + Eqr<'a> {
fn sample<A: 'a + Send, F: FnMut(Box<dyn WrapFunction<'a, A, Self::F<A>>>)>(f: F); fn sample<A: 'a + Send, F: FnMut(Arc<dyn WrapFunction<'a, A, Self::F<A>>>)>(f: F);
} }
pub fn functor_follows_laws<'a, T: Functor<'a> + FunctorTestSuite<'a>>() -> R { pub fn functor_follows_laws<'a, T: Functor<'a> + FunctorTestSuite<'a>>() -> R {
@ -61,7 +55,7 @@ pub fn applicative_follows_laws<'a, T: Applicative<'a> + FunctorTestSuite<'a>>()
}); });
T::sample(|pa| { T::sample(|pa| {
T::sample(|pb| { T::sample(|pb| {
let pa = pa.clone_boxed(); let pa = pa.clone();
res += discard_can_be_expressed_via_seq_or_la2::<T, _, _>(move || pa(2), move || pb(2)); res += discard_can_be_expressed_via_seq_or_la2::<T, _, _>(move || pa(2), move || pb(2));
}) })
}); });
@ -86,10 +80,9 @@ pub fn monad_follows_laws<'a, T: Monad<'a> + FunctorTestSuite<'a>>() -> R {
}); });
T::sample(|pa| { T::sample(|pa| {
T::sample(|pg| { T::sample(|pg| {
let pa = pa.clone_boxed(); let pa = pa.clone();
T::sample(|pf| { T::sample(|pf| {
let pg = Arc::new(pg.clone_boxed()); let pg = pg.clone();
let pf = Arc::new(pf);
res += bind_is_associative::<T, _, _, _>( res += bind_is_associative::<T, _, _, _>(
move |x| pf(x + 5), move |x| pf(x + 5),
move |x| pg(x + 3), move |x| pg(x + 3),
@ -100,7 +93,7 @@ pub fn monad_follows_laws<'a, T: Monad<'a> + FunctorTestSuite<'a>>() -> R {
}); });
T::sample(|pa| { T::sample(|pa| {
T::sample(|pf| { T::sample(|pf| {
let pa = pa.clone_boxed(); let pa = pa.clone();
seq_can_be_expressed_via_bind::<T, _, _, _>(|| pf(|x| x + 3), move || pa(2)); seq_can_be_expressed_via_bind::<T, _, _, _>(|| pf(|x| x + 3), move || pa(2));
}) })
}); });
@ -114,11 +107,11 @@ pub fn monad_follows_laws<'a, T: Monad<'a> + FunctorTestSuite<'a>>() -> R {
}); });
T::sample(|pa| { T::sample(|pa| {
T::sample(|pb| { T::sample(|pb| {
let pa = pa.clone_boxed(); let pa = pa.clone();
res += iterate_can_be_expressed_via_bind::<T, _, _, _>( res += iterate_can_be_expressed_via_bind::<T, _, _, _>(
move || pa(2), move || pa(2),
move || { move || {
let pb = pb.clone_boxed(); let pb = pb.clone();
move |x| pb(x + 3) move |x| pb(x + 3)
}, },
); );