From 8928d25e68c1a692f0c49cd52a4088c77ca383fd Mon Sep 17 00:00:00 2001 From: timofey Date: Fri, 21 Apr 2023 18:06:31 +0000 Subject: [PATCH] ApplicativeTuple --- src/func.rs | 15 +++++++++++++-- src/func/classes/future.rs | 9 +++++++++ src/func/classes/lazy.rs | 9 +++++++++ src/func/classes/option.rs | 9 +++++++++ src/func/classes/result.rs | 9 +++++++++ src/func/classes/solo.rs | 9 +++++++++ src/func/classes/stackless.rs | 9 +++++++++ 7 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/func.rs b/src/func.rs index c0dbf29..176c4c3 100644 --- a/src/func.rs +++ b/src/func.rs @@ -7,7 +7,9 @@ pub mod test_suite; pub mod tests; pub trait WeakFunctor { - type F<'a, A: 'a>: 'a where Self: 'a; + type F<'a, A: 'a>: 'a + where + Self: 'a; } /// Rust-specific implementation of [Functor], respecting `move` semantics. @@ -112,9 +114,18 @@ pub trait ApplicativeLA2: Functor { { Self::la2(|f, a| f(a), ff, fa) } + fn _tuple<'a, A: 'a, B: 'a>((fa, fb): (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> { + Self::la2(|a, b| (a, b), fa, fb) + } } -pub trait Applicative: Functor + ApplicativeSeq + ApplicativeLA2 { +pub trait ApplicativeTuple: Functor { + fn tuple<'a, A: 'a, B: 'a>(fab: (Self::F<'a, A>, Self::F<'a, B>)) -> Self::F<'a, (A, B)> + where + Self: 'a; +} + +pub trait Applicative: Functor + ApplicativeSeq + ApplicativeLA2 + ApplicativeTuple { fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A>; fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B> diff --git a/src/func/classes/future.rs b/src/func/classes/future.rs index 9b2b1a6..53866ca 100644 --- a/src/func/classes/future.rs +++ b/src/func/classes/future.rs @@ -48,6 +48,15 @@ impl ApplicativeLA2 for FutureClass { } } +impl ApplicativeTuple for FutureClass { + 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, + { + Box::pin(async { join!(fa, fb) }) + } +} + impl Applicative for FutureClass { fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> { Box::pin(async { a }) diff --git a/src/func/classes/lazy.rs b/src/func/classes/lazy.rs index ace391b..ccd927c 100644 --- a/src/func/classes/lazy.rs +++ b/src/func/classes/lazy.rs @@ -41,6 +41,15 @@ impl ApplicativeLA2 for LazyClass { } } +impl ApplicativeTuple for LazyClass { + 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, + { + Box::new(|| (fa(), fb())) + } +} + impl Applicative for LazyClass { fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> { Box::new(|| a) diff --git a/src/func/classes/option.rs b/src/func/classes/option.rs index 3b6c751..50d0d22 100644 --- a/src/func/classes/option.rs +++ b/src/func/classes/option.rs @@ -35,6 +35,15 @@ impl ApplicativeLA2 for OptionClass { } } +impl ApplicativeTuple for OptionClass { + 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, + { + Self::pure((fa?, fb?)) + } +} + impl Applicative for OptionClass { fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> { Some(a) diff --git a/src/func/classes/result.rs b/src/func/classes/result.rs index 08e0d74..bb5f21f 100644 --- a/src/func/classes/result.rs +++ b/src/func/classes/result.rs @@ -35,6 +35,15 @@ impl ApplicativeLA2 for ResultClass { } } +impl ApplicativeTuple for ResultClass { + 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, + { + Self::pure((fa?, fb?)) + } +} + impl Applicative for ResultClass { fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> { Ok(a) diff --git a/src/func/classes/solo.rs b/src/func/classes/solo.rs index 07f0ae2..12c0a39 100644 --- a/src/func/classes/solo.rs +++ b/src/func/classes/solo.rs @@ -40,6 +40,15 @@ impl ApplicativeLA2 for SoloClass { } } +impl ApplicativeTuple for SoloClass { + 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, + { + (fa, fb) + } +} + impl Applicative for SoloClass { fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> { a diff --git a/src/func/classes/stackless.rs b/src/func/classes/stackless.rs index 657e27e..63f3be4 100644 --- a/src/func/classes/stackless.rs +++ b/src/func/classes/stackless.rs @@ -163,6 +163,15 @@ impl ApplicativeLA2 for StacklessClass { } } +impl ApplicativeTuple for StacklessClass { + 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, + { + Self::_tuple((fa, fb)) + } +} + impl Applicative for StacklessClass { fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> { Stackless::from(a)