impl ApplicativeSelect
This commit is contained in:
parent
b9cc2a7eed
commit
7caf80f372
@ -146,7 +146,9 @@ pub trait ApplicativeTuple: Functor {
|
|||||||
/// Split into [`Pure`], [`ApplicativeSeq`], [`ApplicativeLA2`] and [`ApplicativeTuple`] due to Rust limitations.
|
/// Split into [`Pure`], [`ApplicativeSeq`], [`ApplicativeLA2`] and [`ApplicativeTuple`] due to Rust limitations.
|
||||||
///
|
///
|
||||||
/// <https://hackage.haskell.org/package/base-4.18.0.0/docs/Control-Applicative.html>
|
/// <https://hackage.haskell.org/package/base-4.18.0.0/docs/Control-Applicative.html>
|
||||||
pub trait Applicative: Pure + ApplicativeSeq + ApplicativeLA2 + ApplicativeTuple {
|
pub trait Applicative:
|
||||||
|
Pure + ApplicativeSeq + ApplicativeLA2 + ApplicativeTuple + ApplicativeSelect
|
||||||
|
{
|
||||||
/// Equivalent of Haskell's `*>`/`>>`.
|
/// Equivalent of Haskell's `*>`/`>>`.
|
||||||
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>
|
||||||
where
|
where
|
||||||
|
@ -12,5 +12,8 @@ pub trait ApplicativeSelect: Functor {
|
|||||||
fb: Self::F<'a, B>,
|
fb: Self::F<'a, B>,
|
||||||
) -> Self::F<'a, C>
|
) -> Self::F<'a, C>
|
||||||
where
|
where
|
||||||
Self: 'a;
|
Self: 'a,
|
||||||
|
{
|
||||||
|
Self::fmap(|a| f(Selected::A(a, fb)), fa)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,26 @@ impl<U: ApplicativeTuple, V: ApplicativeTuple> ApplicativeTuple for CompositionC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<U: ApplicativeSelect, V: ApplicativeSelect> ApplicativeSelect for CompositionClass<U, V> {
|
||||||
|
fn select<'a, A: 'a, B: 'a, C: 'a>(
|
||||||
|
f: impl 'a + FnOnce(Selected<'a, A, B, Self>) -> C,
|
||||||
|
fa: Self::F<'a, A>,
|
||||||
|
fb: Self::F<'a, B>,
|
||||||
|
) -> Self::F<'a, C>
|
||||||
|
where
|
||||||
|
Self: 'a,
|
||||||
|
{
|
||||||
|
U::select(
|
||||||
|
|selected| match selected {
|
||||||
|
Selected::A(ua, fb) => V::fmap(|a| f(Selected::A(a, fb)), ua),
|
||||||
|
Selected::B(fa, ub) => V::fmap(|b| f(Selected::B(fa, b)), ub),
|
||||||
|
},
|
||||||
|
fa,
|
||||||
|
fb,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<U: Applicative, V: Applicative> Applicative for CompositionClass<U, V> {
|
impl<U: Applicative, V: Applicative> Applicative for CompositionClass<U, V> {
|
||||||
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>
|
||||||
where
|
where
|
||||||
|
@ -110,6 +110,8 @@ impl<E: Effect> ApplicativeTuple for EffectClass<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<E: Effect> ApplicativeSelect for EffectClass<E> {}
|
||||||
|
|
||||||
impl<E: Effect> Applicative for EffectClass<E> {
|
impl<E: Effect> Applicative for EffectClass<E> {
|
||||||
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>
|
||||||
where
|
where
|
||||||
|
@ -5,7 +5,10 @@
|
|||||||
|
|
||||||
use std::{future::Future, pin::Pin};
|
use std::{future::Future, pin::Pin};
|
||||||
|
|
||||||
use futures::{future::Shared, join, FutureExt};
|
use futures::{
|
||||||
|
future::{select, Either, Shared},
|
||||||
|
join, FutureExt,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::func::*;
|
use crate::func::*;
|
||||||
|
|
||||||
@ -69,6 +72,24 @@ impl ApplicativeTuple for FutureClass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ApplicativeSelect for FutureClass {
|
||||||
|
fn select<'a, A: 'a, B: 'a, C: 'a>(
|
||||||
|
f: impl 'a + FnOnce(Selected<'a, A, B, Self>) -> C,
|
||||||
|
fa: Self::F<'a, A>,
|
||||||
|
fb: Self::F<'a, B>,
|
||||||
|
) -> Self::F<'a, C>
|
||||||
|
where
|
||||||
|
Self: 'a,
|
||||||
|
{
|
||||||
|
Box::pin(async {
|
||||||
|
match select(fa, fb).await {
|
||||||
|
Either::Left((a, fb)) => f(Selected::A(a, fb)),
|
||||||
|
Either::Right((b, fa)) => f(Selected::B(fa, b)),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Applicative for FutureClass {
|
impl Applicative for FutureClass {
|
||||||
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> {
|
||||||
Box::pin(async { join!(fa, fb).1 })
|
Box::pin(async { join!(fa, fb).1 })
|
||||||
|
@ -68,6 +68,8 @@ impl ApplicativeTuple for LazyClass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ApplicativeSelect for LazyClass {}
|
||||||
|
|
||||||
impl Applicative for LazyClass {
|
impl Applicative for LazyClass {
|
||||||
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> {
|
||||||
drop(fa);
|
drop(fa);
|
||||||
|
@ -72,6 +72,8 @@ impl ApplicativeTuple for OptionClass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ApplicativeSelect for OptionClass {}
|
||||||
|
|
||||||
impl Applicative for OptionClass {
|
impl Applicative for OptionClass {
|
||||||
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> {
|
||||||
fa?;
|
fa?;
|
||||||
|
@ -84,6 +84,8 @@ impl<T: ApplicativeTuple, O: DeriveApplicative> ApplicativeTuple for OverloadCla
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: ApplicativeTuple, O: DeriveApplicative> ApplicativeSelect for OverloadClass<T, O> {}
|
||||||
|
|
||||||
impl<T: Applicative, O: DeriveApplicative> Applicative for OverloadClass<T, O> {
|
impl<T: Applicative, O: DeriveApplicative> Applicative for OverloadClass<T, O> {
|
||||||
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>
|
||||||
where
|
where
|
||||||
|
@ -84,6 +84,8 @@ impl<E> ApplicativeTuple for ResultClass<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<E> ApplicativeSelect for ResultClass<E> {}
|
||||||
|
|
||||||
impl<E> Applicative for ResultClass<E> {
|
impl<E> Applicative for ResultClass<E> {
|
||||||
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>
|
||||||
where
|
where
|
||||||
|
@ -60,6 +60,8 @@ impl ApplicativeTuple for SoloClass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ApplicativeSelect for SoloClass {}
|
||||||
|
|
||||||
impl Applicative for SoloClass {
|
impl Applicative for SoloClass {
|
||||||
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> {
|
||||||
drop(fa);
|
drop(fa);
|
||||||
|
@ -187,6 +187,8 @@ impl ApplicativeTuple for StacklessClass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ApplicativeSelect for StacklessClass {}
|
||||||
|
|
||||||
impl Applicative for StacklessClass {
|
impl Applicative for StacklessClass {
|
||||||
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>
|
||||||
where
|
where
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
use std::{future::Future, pin::Pin};
|
use std::{future::Future, pin::Pin};
|
||||||
|
|
||||||
use futures::{future::Shared, try_join, FutureExt};
|
use futures::{
|
||||||
|
future::{try_select, Either, Shared},
|
||||||
|
try_join, FutureExt,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::func::*;
|
use crate::func::*;
|
||||||
|
|
||||||
@ -79,6 +82,26 @@ impl<E> ApplicativeTuple for TryFutureClass<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<E> ApplicativeSelect for TryFutureClass<E> {
|
||||||
|
fn select<'a, A: 'a, B: 'a, C: 'a>(
|
||||||
|
f: impl 'a + FnOnce(Selected<'a, A, B, Self>) -> C,
|
||||||
|
fa: Self::F<'a, A>,
|
||||||
|
fb: Self::F<'a, B>,
|
||||||
|
) -> Self::F<'a, C>
|
||||||
|
where
|
||||||
|
Self: 'a,
|
||||||
|
{
|
||||||
|
Box::pin(async {
|
||||||
|
match try_select(fa, fb).await {
|
||||||
|
Ok(Either::Left((a, fb))) => Ok(f(Selected::A(a, fb))),
|
||||||
|
Ok(Either::Right((b, fa))) => Ok(f(Selected::B(fa, b))),
|
||||||
|
Err(Either::Left((e, _))) => Err(e),
|
||||||
|
Err(Either::Right((e, _))) => Err(e),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<E> Applicative for TryFutureClass<E> {
|
impl<E> Applicative for TryFutureClass<E> {
|
||||||
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>
|
||||||
where
|
where
|
||||||
|
Loading…
Reference in New Issue
Block a user