diff --git a/src/func.rs b/src/func.rs index cfb166d..63a8288 100644 --- a/src/func.rs +++ b/src/func.rs @@ -150,11 +150,9 @@ pub trait ApplicativeLA2: Functor { } /// Part of [`Applicative`] responsible for Rust-style result combination, specifically for tuples. -pub trait ApplicativeTuple: Functor { +pub trait ApplicativeTuple<'a>: 'a + Functor { /// Similar to Haskell's `listA2` but with [Iterator::collect]-ish semantics. - fn tuple<'a, A: 'a, B: 'a>(fab: (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> - where - Self: 'a; + fn tuple(fab: (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)>; } /// Equivalent of Haskell's `Applicative`. @@ -162,7 +160,7 @@ pub trait ApplicativeTuple: Functor { /// /// pub trait Applicative<'a>: - Pure + ApplicativeSeq + ApplicativeLA2 + ApplicativeTuple + ApplicativeSelect<'a> + Pure + ApplicativeSeq + ApplicativeLA2 + 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/instances/composition.rs b/src/func/instances/composition.rs index 679193d..5d9d5eb 100644 --- a/src/func/instances/composition.rs +++ b/src/func/instances/composition.rs @@ -63,11 +63,10 @@ impl ApplicativeLA2 for CompositionInstanc } } -impl ApplicativeTuple for CompositionInstance { - fn tuple<'a, A: 'a, B: 'a>(fab: (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> - where - Self: 'a, - { +impl<'a, U: ApplicativeTuple<'a>, V: ApplicativeTuple<'a>> ApplicativeTuple<'a> + for CompositionInstance +{ + fn tuple(fab: (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { U::fmap(V::tuple, U::tuple(fab)) } } diff --git a/src/func/instances/effect.rs b/src/func/instances/effect.rs index 1c063c7..76e8440 100644 --- a/src/func/instances/effect.rs +++ b/src/func/instances/effect.rs @@ -98,11 +98,8 @@ impl ApplicativeLA2 for EffectInstance { } } -impl ApplicativeTuple for EffectInstance { - fn tuple<'a, A: 'a, B: 'a>((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> - where - Self: 'a, - { +impl<'a, E: 'a + Effect> ApplicativeTuple<'a> for EffectInstance { + fn tuple((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { WithEffect { value: (fa.value, fb.value), effect: E::e_seq(fa.effect, fb.effect), diff --git a/src/func/instances/future.rs b/src/func/instances/future.rs index 8eee7a9..2eaa390 100644 --- a/src/func/instances/future.rs +++ b/src/func/instances/future.rs @@ -63,11 +63,8 @@ impl ApplicativeLA2 for FutureInstance { } } -impl ApplicativeTuple for FutureInstance { - fn tuple<'a, A: 'a, B: 'a>((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> - where - Self: 'a, - { +impl<'a> ApplicativeTuple<'a> for FutureInstance { + fn tuple((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { Box::pin(async { join!(fa, fb) }) } } diff --git a/src/func/instances/lazy.rs b/src/func/instances/lazy.rs index 759f837..5b2afab 100644 --- a/src/func/instances/lazy.rs +++ b/src/func/instances/lazy.rs @@ -59,11 +59,8 @@ impl ApplicativeLA2 for LazyInstance { } } -impl ApplicativeTuple for LazyInstance { - fn tuple<'a, A: 'a, B: 'a>((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> - where - Self: 'a, - { +impl<'a> ApplicativeTuple<'a> for LazyInstance { + fn tuple((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { Box::new(|| (fa(), fb())) } } diff --git a/src/func/instances/option.rs b/src/func/instances/option.rs index 119a5c6..1d9afb1 100644 --- a/src/func/instances/option.rs +++ b/src/func/instances/option.rs @@ -63,11 +63,8 @@ impl ApplicativeLA2 for OptionInstance { } } -impl ApplicativeTuple for OptionInstance { - fn tuple<'a, A: 'a, B: 'a>((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> - where - Self: 'a, - { +impl<'a> ApplicativeTuple<'a> for OptionInstance { + fn tuple((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { Self::pure((fa?, fb?)) } } diff --git a/src/func/instances/overload.rs b/src/func/instances/overload.rs index 2688fde..48360ca 100644 --- a/src/func/instances/overload.rs +++ b/src/func/instances/overload.rs @@ -75,11 +75,10 @@ impl ApplicativeLA2 for OverloadInstanc } } -impl ApplicativeTuple for OverloadInstance { - fn tuple<'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: ApplicativeTuple<'a>, O: 'a + DeriveApplicative> ApplicativeTuple<'a> + for OverloadInstance +{ + fn tuple(fab: (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { T::tuple(fab) } } diff --git a/src/func/instances/result.rs b/src/func/instances/result.rs index 4a1722d..2c5c39f 100644 --- a/src/func/instances/result.rs +++ b/src/func/instances/result.rs @@ -75,11 +75,8 @@ impl ApplicativeLA2 for ResultInstance { } } -impl ApplicativeTuple for ResultInstance { - fn tuple<'a, A: 'a, B: 'a>((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> - where - Self: 'a, - { +impl<'a, E: 'a> ApplicativeTuple<'a> for ResultInstance { + fn tuple((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { Self::pure((fa?, fb?)) } } diff --git a/src/func/instances/solo.rs b/src/func/instances/solo.rs index f973b4b..9ebf8b6 100644 --- a/src/func/instances/solo.rs +++ b/src/func/instances/solo.rs @@ -51,11 +51,8 @@ impl ApplicativeLA2 for SoloInstance { } } -impl ApplicativeTuple for SoloInstance { - fn tuple<'a, A: 'a, B: 'a>((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> - where - Self: 'a, - { +impl<'a> ApplicativeTuple<'a> for SoloInstance { + fn tuple((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { (fa, fb) } } diff --git a/src/func/instances/stackless.rs b/src/func/instances/stackless.rs index 4d6de93..37e9661 100644 --- a/src/func/instances/stackless.rs +++ b/src/func/instances/stackless.rs @@ -178,11 +178,8 @@ impl ApplicativeLA2 for StacklessInstance { } } -impl ApplicativeTuple for StacklessInstance { - fn tuple<'a, A: 'a, B: 'a>((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> - where - Self: 'a, - { +impl<'a> ApplicativeTuple<'a> for StacklessInstance { + fn tuple((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { Self::_tuple_via_la2((fa, fb)) } } diff --git a/src/func/instances/tryfuture.rs b/src/func/instances/tryfuture.rs index c22f24c..fc0a105 100644 --- a/src/func/instances/tryfuture.rs +++ b/src/func/instances/tryfuture.rs @@ -73,11 +73,8 @@ impl ApplicativeLA2 for TryFutureInstance { } } -impl ApplicativeTuple for TryFutureInstance { - fn tuple<'a, A: 'a, B: 'a>((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> - where - Self: 'a, - { +impl<'a, E: 'a> ApplicativeTuple<'a> for TryFutureInstance { + fn tuple((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { Box::pin(async { try_join!(fa, fb) }) } }