ApplicativeTuple

This commit is contained in:
AF 2023-04-21 18:06:31 +00:00
parent e408341b18
commit 8928d25e68
7 changed files with 67 additions and 2 deletions

View File

@ -7,7 +7,9 @@ pub mod test_suite;
pub mod tests; pub mod tests;
pub trait WeakFunctor { 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. /// Rust-specific implementation of [Functor], respecting `move` semantics.
@ -112,9 +114,18 @@ pub trait ApplicativeLA2: Functor {
{ {
Self::la2(|f, a| f(a), ff, fa) 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 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> fn discard_first<'a, A: 'a, B: 'a>(fa: Self::F<'a, A>, fb: Self::F<'a, B>) -> Self::F<'a, B>

View File

@ -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 { impl Applicative for FutureClass {
fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> { fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> {
Box::pin(async { a }) Box::pin(async { a })

View File

@ -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 { impl Applicative for LazyClass {
fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> { fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> {
Box::new(|| a) Box::new(|| a)

View File

@ -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 { impl Applicative for OptionClass {
fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> { fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> {
Some(a) Some(a)

View File

@ -35,6 +35,15 @@ impl<E> ApplicativeLA2 for ResultClass<E> {
} }
} }
impl<E> ApplicativeTuple for ResultClass<E> {
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<E> Applicative for ResultClass<E> { impl<E> Applicative for ResultClass<E> {
fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> { fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> {
Ok(a) Ok(a)

View File

@ -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 { impl Applicative for SoloClass {
fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> { fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> {
a a

View File

@ -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 { impl Applicative for StacklessClass {
fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> { fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A> {
Stackless::from(a) Stackless::from(a)