From 7f69b10e2e1ccf9fdebe6f7c16616bed6c3fe7d3 Mon Sep 17 00:00:00 2001 From: timofey Date: Fri, 26 May 2023 09:21:09 +0000 Subject: [PATCH] `ApplicativeSeq`+`ApplicativeLA2` lift lifetime --- src/func.rs | 18 ++++------ src/func/derivations.rs | 56 +++++++------------------------ src/func/instances/composition.rs | 22 ++++++------ src/func/instances/effect.rs | 8 ++--- src/func/instances/future.rs | 8 ++--- src/func/instances/lazy.rs | 8 ++--- src/func/instances/option.rs | 8 ++--- src/func/instances/overload.rs | 22 ++++++------ src/func/instances/result.rs | 18 ++++------ src/func/instances/solo.rs | 8 ++--- src/func/instances/stackless.rs | 18 ++++------ src/func/instances/tryfuture.rs | 18 ++++------ 12 files changed, 78 insertions(+), 134 deletions(-) diff --git a/src/func.rs b/src/func.rs index fe87ced..8ca9e09 100644 --- a/src/func.rs +++ b/src/func.rs @@ -127,26 +127,22 @@ pub trait Pure: Functor { } /// Part of [`Applicative`] responsible for Haskell's sequential application `<*>`. -pub trait ApplicativeSeq: Functor { +pub trait ApplicativeSeq<'a>: 'a + Functor { /// Equivalent of Haskell's `<*>`. - fn seq<'a, A: 'a, B: 'a>( + fn seq( ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, fa: Self::F<'a, A>, - ) -> Self::F<'a, B> - where - Self: 'a; + ) -> Self::F<'a, B>; } /// Part of [`Applicative`] responsible for Haskell's result combination `listA2`. -pub trait ApplicativeLA2: Functor { +pub trait ApplicativeLA2<'a>: 'a + Functor { /// Equivalent of Haskell's `listA2`. - fn la2<'a, A: 'a, B: 'a, C: 'a>( + fn la2( f: impl 'a + FnOnce(A, B) -> C, fa: Self::F<'a, A>, fb: Self::F<'a, B>, - ) -> Self::F<'a, C> - where - Self: 'a; + ) -> Self::F<'a, C>; } /// Part of [`Applicative`] responsible for Rust-style result combination, specifically for tuples. @@ -160,7 +156,7 @@ pub trait ApplicativeTuple<'a>: 'a + Functor { /// /// pub trait Applicative<'a>: - Pure + ApplicativeSeq + ApplicativeLA2 + ApplicativeTuple<'a> + ApplicativeSelect<'a> + Pure + ApplicativeSeq<'a> + ApplicativeLA2<'a> + ApplicativeTuple<'a> + ApplicativeSelect<'a> { /// Equivalent of Haskell's `*>`/`>>`. fn discard_first(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> { diff --git a/src/func/derivations.rs b/src/func/derivations.rs index b961f4d..78de10e 100644 --- a/src/func/derivations.rs +++ b/src/func/derivations.rs @@ -16,65 +16,35 @@ pub fn bind<'a, T: Monad<'a>, A: 'a, B: 'a>( move |fa| T::bind(fa, f) } -pub trait ApplicativeLA2ViaSeq: ApplicativeSeq { - fn _la2_via_seq<'a, A: 'a, B: 'a, C: 'a>( +pub trait ApplicativeLA2ViaSeq<'a>: ApplicativeSeq<'a> { + fn _la2_via_seq( f: impl 'a + FnOnce(A, B) -> C, fa: Self::F<'a, A>, fb: Self::F<'a, B>, - ) -> Self::F<'a, C> - where - Self: 'a; -} - -impl ApplicativeLA2ViaSeq for T { - fn _la2_via_seq<'a, A: 'a, B: 'a, C: 'a>( - f: impl 'a + FnOnce(A, B) -> C, - fa: Self::F<'a, A>, - fb: Self::F<'a, B>, - ) -> Self::F<'a, C> - where - Self: 'a, - { + ) -> Self::F<'a, C> { Self::seq(Self::fmap(|a| |b| f(a, b), fa), fb) } } -pub trait ApplicativeSeqViaLA2: ApplicativeLA2 { - fn _seq_via_la2<'a, A: 'a, B: 'a>( - ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, - fa: Self::F<'a, A>, - ) -> Self::F<'a, B> - where - Self: 'a; -} +impl<'a, T: ApplicativeSeq<'a>> ApplicativeLA2ViaSeq<'a> for T {} -impl ApplicativeSeqViaLA2 for T { - fn _seq_via_la2<'a, A: 'a, B: 'a>( +pub trait ApplicativeSeqViaLA2<'a>: ApplicativeLA2<'a> { + fn _seq_via_la2( ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, fa: Self::F<'a, A>, - ) -> Self::F<'a, B> - where - Self: 'a, - { + ) -> Self::F<'a, B> { Self::la2(|f, a| f(a), ff, fa) } } -pub trait ApplicativeTupleViaLA2: ApplicativeLA2 { - fn _tuple_via_la2<'a, A: 'a, B: 'a>( - fab: (Self::F<'a, A>, Self::F<'a, B>), - ) -> Self::F<'a, (A, B)> - where - Self: 'a; -} +impl<'a, T: ApplicativeLA2<'a>> ApplicativeSeqViaLA2<'a> for T {} -impl ApplicativeTupleViaLA2 for T { - fn _tuple_via_la2<'a, A: 'a, B: 'a>( +pub trait ApplicativeTupleViaLA2<'a>: ApplicativeLA2<'a> { + fn _tuple_via_la2( (fa, fb): (Self::F<'a, A>, Self::F<'a, B>), - ) -> Self::F<'a, (A, B)> - where - Self: 'a, - { + ) -> Self::F<'a, (A, B)> { Self::la2(|a, b| (a, b), fa, fb) } } + +impl<'a, T: ApplicativeLA2<'a>> ApplicativeTupleViaLA2<'a> for T {} diff --git a/src/func/instances/composition.rs b/src/func/instances/composition.rs index 5d9d5eb..d1df25f 100644 --- a/src/func/instances/composition.rs +++ b/src/func/instances/composition.rs @@ -38,27 +38,25 @@ impl Pure for CompositionInstance { } } -impl ApplicativeSeq for CompositionInstance { - fn seq<'a, A: 'a, B: 'a>( +impl<'a, U: ApplicativeLA2<'a>, V: ApplicativeSeq<'a>> ApplicativeSeq<'a> + for CompositionInstance +{ + fn seq( ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, fa: Self::F<'a, A>, - ) -> Self::F<'a, B> - where - Self: 'a, - { + ) -> Self::F<'a, B> { U::la2(|uf, ua| V::seq(uf, ua), ff, fa) } } -impl ApplicativeLA2 for CompositionInstance { - fn la2<'a, A: 'a, B: 'a, C: 'a>( +impl<'a, U: ApplicativeLA2<'a>, V: ApplicativeLA2<'a>> ApplicativeLA2<'a> + for CompositionInstance +{ + fn la2( f: impl 'a + FnOnce(A, B) -> C, fa: Self::F<'a, A>, fb: Self::F<'a, B>, - ) -> Self::F<'a, C> - where - Self: 'a, - { + ) -> Self::F<'a, C> { U::la2(|ua, ub| V::la2(f, ua, ub), fa, fb) } } diff --git a/src/func/instances/effect.rs b/src/func/instances/effect.rs index 76e8440..f2c5558 100644 --- a/src/func/instances/effect.rs +++ b/src/func/instances/effect.rs @@ -67,8 +67,8 @@ impl Pure for EffectInstance { } } -impl ApplicativeSeq for EffectInstance { - fn seq<'a, A: 'a, B: 'a>( +impl<'a, E: 'a + Effect> ApplicativeSeq<'a> for EffectInstance { + fn seq( ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, fa: Self::F<'a, A>, ) -> Self::F<'a, B> @@ -82,8 +82,8 @@ impl ApplicativeSeq for EffectInstance { } } -impl ApplicativeLA2 for EffectInstance { - fn la2<'a, A: 'a, B: 'a, C: 'a>( +impl<'a, E: 'a + Effect> ApplicativeLA2<'a> for EffectInstance { + fn la2( f: impl 'a + FnOnce(A, B) -> C, fa: Self::F<'a, A>, fb: Self::F<'a, B>, diff --git a/src/func/instances/future.rs b/src/func/instances/future.rs index 2eaa390..ffda80e 100644 --- a/src/func/instances/future.rs +++ b/src/func/instances/future.rs @@ -38,8 +38,8 @@ impl Pure for FutureInstance { } } -impl ApplicativeSeq for FutureInstance { - fn seq<'a, A: 'a, B: 'a>( +impl<'a> ApplicativeSeq<'a> for FutureInstance { + fn seq( ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, fa: Self::F<'a, A>, ) -> Self::F<'a, B> { @@ -50,8 +50,8 @@ impl ApplicativeSeq for FutureInstance { } } -impl ApplicativeLA2 for FutureInstance { - fn la2<'a, A: 'a, B: 'a, C: 'a>( +impl<'a> ApplicativeLA2<'a> for FutureInstance { + fn la2( f: impl 'a + FnOnce(A, B) -> C, fa: Self::F<'a, A>, fb: Self::F<'a, B>, diff --git a/src/func/instances/lazy.rs b/src/func/instances/lazy.rs index 5b2afab..655548c 100644 --- a/src/func/instances/lazy.rs +++ b/src/func/instances/lazy.rs @@ -40,8 +40,8 @@ impl Pure for LazyInstance { } } -impl ApplicativeSeq for LazyInstance { - fn seq<'a, A: 'a, B: 'a>( +impl<'a> ApplicativeSeq<'a> for LazyInstance { + fn seq( ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, fa: Self::F<'a, A>, ) -> Self::F<'a, B> { @@ -49,8 +49,8 @@ impl ApplicativeSeq for LazyInstance { } } -impl ApplicativeLA2 for LazyInstance { - fn la2<'a, A: 'a, B: 'a, C: 'a>( +impl<'a> ApplicativeLA2<'a> for LazyInstance { + fn la2( f: impl 'a + FnOnce(A, B) -> C, fa: Self::F<'a, A>, fb: Self::F<'a, B>, diff --git a/src/func/instances/option.rs b/src/func/instances/option.rs index 1d9afb1..6bc19cb 100644 --- a/src/func/instances/option.rs +++ b/src/func/instances/option.rs @@ -44,8 +44,8 @@ impl Pure for OptionInstance { } } -impl ApplicativeSeq for OptionInstance { - fn seq<'a, A: 'a, B: 'a>( +impl<'a> ApplicativeSeq<'a> for OptionInstance { + fn seq( ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, fa: Self::F<'a, A>, ) -> Self::F<'a, B> { @@ -53,8 +53,8 @@ impl ApplicativeSeq for OptionInstance { } } -impl ApplicativeLA2 for OptionInstance { - fn la2<'a, A: 'a, B: 'a, C: 'a>( +impl<'a> ApplicativeLA2<'a> for OptionInstance { + fn la2( f: impl 'a + FnOnce(A, B) -> C, fa: Self::F<'a, A>, fb: Self::F<'a, B>, diff --git a/src/func/instances/overload.rs b/src/func/instances/overload.rs index 48360ca..7656998 100644 --- a/src/func/instances/overload.rs +++ b/src/func/instances/overload.rs @@ -50,27 +50,25 @@ impl Pure for OverloadInstance { } } -impl ApplicativeSeq for OverloadInstance { - fn seq<'a, A: 'a, B: 'a>( +impl<'a, T: ApplicativeSeq<'a>, O: 'a + DeriveApplicative> ApplicativeSeq<'a> + for OverloadInstance +{ + fn seq( ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, fa: Self::F<'a, A>, - ) -> Self::F<'a, B> - where - Self: 'a, - { + ) -> Self::F<'a, B> { T::seq(ff, fa) } } -impl ApplicativeLA2 for OverloadInstance { - fn la2<'a, A: 'a, B: 'a, C: 'a>( +impl<'a, T: ApplicativeLA2<'a>, O: 'a + DeriveApplicative> ApplicativeLA2<'a> + for OverloadInstance +{ + fn la2( f: impl 'a + FnOnce(A, B) -> C, fa: Self::F<'a, A>, fb: Self::F<'a, B>, - ) -> Self::F<'a, C> - where - Self: 'a, - { + ) -> Self::F<'a, C> { T::la2(f, fa, fb) } } diff --git a/src/func/instances/result.rs b/src/func/instances/result.rs index 2c5c39f..915617a 100644 --- a/src/func/instances/result.rs +++ b/src/func/instances/result.rs @@ -50,27 +50,21 @@ impl Pure for ResultInstance { } } -impl ApplicativeSeq for ResultInstance { - fn seq<'a, A: 'a, B: 'a>( +impl<'a, E: 'a> ApplicativeSeq<'a> for ResultInstance { + fn seq( ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, fa: Self::F<'a, A>, - ) -> Self::F<'a, B> - where - Self: 'a, - { + ) -> Self::F<'a, B> { Self::pure(ff?(fa?)) } } -impl ApplicativeLA2 for ResultInstance { - fn la2<'a, A: 'a, B: 'a, C: 'a>( +impl<'a, E: 'a> ApplicativeLA2<'a> for ResultInstance { + fn la2( f: impl 'a + FnOnce(A, B) -> C, fa: Self::F<'a, A>, fb: Self::F<'a, B>, - ) -> Self::F<'a, C> - where - Self: 'a, - { + ) -> Self::F<'a, C> { Self::pure(f(fa?, fb?)) } } diff --git a/src/func/instances/solo.rs b/src/func/instances/solo.rs index 9ebf8b6..2b4d7e2 100644 --- a/src/func/instances/solo.rs +++ b/src/func/instances/solo.rs @@ -32,8 +32,8 @@ impl Pure for SoloInstance { } } -impl ApplicativeSeq for SoloInstance { - fn seq<'a, A: 'a, B: 'a>( +impl<'a> ApplicativeSeq<'a> for SoloInstance { + fn seq( ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, fa: Self::F<'a, A>, ) -> Self::F<'a, B> { @@ -41,8 +41,8 @@ impl ApplicativeSeq for SoloInstance { } } -impl ApplicativeLA2 for SoloInstance { - fn la2<'a, A: 'a, B: 'a, C: 'a>( +impl<'a> ApplicativeLA2<'a> for SoloInstance { + fn la2( f: impl 'a + FnOnce(A, B) -> C, fa: Self::F<'a, A>, fb: Self::F<'a, B>, diff --git a/src/func/instances/stackless.rs b/src/func/instances/stackless.rs index 37e9661..1d39554 100644 --- a/src/func/instances/stackless.rs +++ b/src/func/instances/stackless.rs @@ -153,27 +153,21 @@ impl Pure for StacklessInstance { } } -impl ApplicativeSeq for StacklessInstance { - fn seq<'a, A: 'a, B: 'a>( +impl<'a> ApplicativeSeq<'a> for StacklessInstance { + fn seq( ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, fa: Self::F<'a, A>, - ) -> Self::F<'a, B> - where - Self: 'a, - { + ) -> Self::F<'a, B> { ff.bind(|f| fa.map(f)) } } -impl ApplicativeLA2 for StacklessInstance { - fn la2<'a, A: 'a, B: 'a, C: 'a>( +impl<'a> ApplicativeLA2<'a> for StacklessInstance { + fn la2( f: impl 'a + FnOnce(A, B) -> C, fa: Self::F<'a, A>, fb: Self::F<'a, B>, - ) -> Self::F<'a, C> - where - Self: 'a, - { + ) -> Self::F<'a, C> { Self::_la2_via_seq(f, fa, fb) } } diff --git a/src/func/instances/tryfuture.rs b/src/func/instances/tryfuture.rs index fc0a105..044315c 100644 --- a/src/func/instances/tryfuture.rs +++ b/src/func/instances/tryfuture.rs @@ -42,14 +42,11 @@ impl Pure for TryFutureInstance { } } -impl ApplicativeSeq for TryFutureInstance { - fn seq<'a, A: 'a, B: 'a>( +impl<'a, E: 'a> ApplicativeSeq<'a> for TryFutureInstance { + fn seq( ff: Self::F<'a, impl 'a + FnOnce(A) -> B>, fa: Self::F<'a, A>, - ) -> Self::F<'a, B> - where - Self: 'a, - { + ) -> Self::F<'a, B> { Box::pin(async { let (f, a) = try_join!(ff, fa)?; Ok(f(a)) @@ -57,15 +54,12 @@ impl ApplicativeSeq for TryFutureInstance { } } -impl ApplicativeLA2 for TryFutureInstance { - fn la2<'a, A: 'a, B: 'a, C: 'a>( +impl<'a, E: 'a> ApplicativeLA2<'a> for TryFutureInstance { + fn la2( f: impl 'a + FnOnce(A, B) -> C, fa: Self::F<'a, A>, fb: Self::F<'a, B>, - ) -> Self::F<'a, C> - where - Self: 'a, - { + ) -> Self::F<'a, C> { Box::pin(async { let (a, b) = try_join!(fa, fb)?; Ok(f(a, b))