diff --git a/src/func/instances/option.rs b/src/func/instances/option.rs index b87a1a5..df44f84 100644 --- a/src/func/instances/option.rs +++ b/src/func/instances/option.rs @@ -13,6 +13,7 @@ //! [`solo`]: super::solo use crate::func::class_prelude::*; + #[derive(SharedFunctorAny)] pub struct OptionInstance; @@ -79,8 +80,8 @@ impl<'a> Applicative<'a> for OptionInstance { } fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { - fb?; - fa + let a = fa?; + fb.map(|_| a) } } diff --git a/src/func/instances/result.rs b/src/func/instances/result.rs index b1b26dd..4ae6bcc 100644 --- a/src/func/instances/result.rs +++ b/src/func/instances/result.rs @@ -99,8 +99,8 @@ impl<'a, E: 'a + Send> Applicative<'a> for ResultInstance { } fn discard_second(fa: Self::F, fb: Self::F) -> Self::F { - fb?; - fa + let a = fa?; + fb.map(|_| a) } } @@ -264,3 +264,33 @@ impl<'a, T: Monad<'a>> MonadFailAny<'a> for ResultFailOver { T::fmap(wa, ::rotate_out) } } + +#[cfg(test)] +mod result_tests { + use super::{test_suite, tests, ResultInstance}; + + type T = ResultInstance; + + impl<'a> tests::Eqr<'a> for T { + fn eqr( + name: &'a str, + left: Self::F, + right: Self::F, + ) -> tests::R { + tests::eqr(name, left, right) + } + } + + impl<'a> test_suite::FunctorTestSuite<'a> for T { + fn sample Self::F))>(mut f: F) { + f(&|_| Err(false)); + f(&|_| Err(true)); + f(&|a| Ok(a)); + } + } + + #[test] + fn monad_follows_laws() { + test_suite::monad_follows_laws::().unwrap(); + } +} diff --git a/src/func/tests.rs b/src/func/tests.rs index 3db96c0..185dfac 100644 --- a/src/func/tests.rs +++ b/src/func/tests.rs @@ -220,7 +220,7 @@ pub fn fmap_can_be_expressed_via_seq< pub fn discard_can_be_expressed_via_seq_or_la2< 'a, T: Applicative<'a> + Eqr<'a>, - A: 'a + Send, + A: 'a + Send + Debug + PartialEq, B: 'a + Send + Debug + PartialEq, >( fa0: impl 'a + Fn() -> T::F, @@ -232,8 +232,8 @@ pub fn discard_can_be_expressed_via_seq_or_la2< T::seq(T::replace(fa0(), |b| b), fb0()), ) + T::eqr( "discard via la2: u <* v = liftA2 const u v", - T::discard_second(fb0(), fa0()), - T::la2(fb0(), fa0(), |b, _| b), + T::discard_second(fa0(), fb0()), + T::la2(fa0(), fb0(), |a, _| a), ) }