radn-rs/src/func/applicative_select.rs
2023-05-30 00:09:38 +00:00

30 lines
938 B
Rust

use super::*;
pub enum Selected<'a, A: 'a, B: 'a, T: ?Sized + WeakFunctor<'a>> {
A(A, T::F<B>),
B(T::F<A>, B),
}
/// See [`ApplicativeSelect::select`].
pub type SelectedWrapped<'a, A, B, T> = Wrap<'a, Selected<'a, A, B, T>, T>;
/// Part of [`Applicative`] responsible for choosing the first value.
pub trait ApplicativeSelect<'a>: Functor<'a> {
fn select<A: 'a, B: 'a>(fa: Self::F<A>, fb: Self::F<B>) -> SelectedWrapped<'a, A, B, Self> {
Self::fmap(fa, |a| Selected::A(a, fb))
}
}
pub trait ApplicativeSelectExt<'a>: ApplicativeSelect<'a> {
/// Shorthand for [`Functor::fmap`]&#8728;[`ApplicativeSelect::select`].
fn select_map<A: 'a, B: 'a, C: 'a>(
fa: Self::F<A>,
fb: Self::F<B>,
f: impl 'a + FnOnce(Selected<'a, A, B, Self>) -> C,
) -> Self::F<C> {
Self::fmap(Self::select(fa, fb), f)
}
}
impl<'a, T: ApplicativeSelect<'a>> ApplicativeSelectExt<'a> for T {}