use crate::prelude::*;
pub trait Alternative<A: Clone>: Applicative<A> {
type Alternative<B: Clone>: Alternative<B, Alternative<A> = Self>;
#[must_use]
fn empty() -> Self;
#[must_use]
fn either<F: FnOnce() -> Self>(self, make_other: F) -> Self;
#[inline(always)]
#[must_use]
fn guard(b: bool) -> Self::Alternative<()>
where
Self::Alternative<()>: Applicative<(), Applicative<()> = Self::Alternative<()>>,
{
if b {
consume::<Self::Alternative<()>, ()>(())
} else {
empty()
}
}
}
#[inline(always)]
#[must_use]
pub fn empty<AA: Alternative<A>, A: Clone>() -> AA {
AA::empty()
}
#[inline(always)]
#[must_use]
pub fn either<AA: Alternative<A>, A: Clone, F: FnOnce() -> AA>(f1: F, f2: F) -> AA {
f1().either(f2)
}
#[inline(always)]
#[must_use]
pub fn guard<A: Alternative<(), Applicative<()> = A>>(b: bool) -> A {
if b {
consume(())
} else {
empty()
}
}