pub trait Mode { type Output; fn bind(f: F) -> Self::Output where F: FnOnce() -> T; fn map(t: Self::Output, f: F) -> Self::Output where F: FnOnce(T) -> U; fn combine(t: Self::Output, u: Self::Output, f: F) -> Self::Output where F: FnOnce(T, U) -> V; } pub struct Emit; impl Mode for Emit { type Output = T; fn bind(f: F) -> Self::Output where F: FnOnce() -> T, { f() } fn map(t: Self::Output, f: F) -> Self::Output where F: FnOnce(T) -> U, { f(t) } fn combine(t: Self::Output, u: Self::Output, f: F) -> Self::Output where F: FnOnce(T, U) -> V, { f(t, u) } } pub struct Check; impl Mode for Check { type Output = (); fn bind(_: F) -> Self::Output where F: FnOnce() -> T, { } fn map(_: Self::Output, _: F) -> Self::Output where F: FnOnce(T) -> U, { } fn combine(_: Self::Output, _: Self::Output, _: F) -> Self::Output where F: FnOnce(T, U) -> V, { } }