pub trait Binary<A, B> {
type Output;
fn with(self, a: A) -> impl Fn(B) -> Self::Output + Clone + Send
where
A: Clone + Send;
fn then<C>(
self,
f: impl Fn(Self::Output) -> C + Clone + Send,
) -> impl Fn(A, B) -> C + Clone + Send;
}
impl<F, A, B, O> Binary<A, B> for F
where
F: Fn(A, B) -> O + Clone + Send,
{
type Output = O;
fn with(self, a: A) -> impl Fn(B) -> Self::Output + Clone + Send
where
A: Clone + Send,
{
move |b| self(a.clone(), b)
}
fn then<C>(
self,
f: impl Fn(Self::Output) -> C + Clone + Send,
) -> impl Fn(A, B) -> C + Clone + Send {
move |a, b| f(self(a, b))
}
}