#[fp_macros::document_module]
pub(crate) mod inner {
use {
crate::{
classes::{
RefSemimonad,
Semimonad,
},
dispatch::{
Ref,
Val,
},
kinds::*,
},
fp_macros::*,
};
#[document_type_parameters(
"The lifetime of the values.",
"The brand of the monad.",
"The type of the value inside the monad.",
"The type of the result.",
"The container type (owned or borrowed), inferred from the argument.",
"Dispatch marker type, inferred automatically."
)]
#[document_parameters("The closure implementing this dispatch.")]
pub trait BindDispatch<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a, B: 'a, FA, Marker> {
#[document_signature]
#[document_parameters("The monadic value.")]
#[document_returns("The result of binding.")]
#[document_examples]
fn dispatch(
self,
ma: FA,
) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>);
}
#[document_type_parameters(
"The lifetime.",
"The brand.",
"The input type.",
"The output type.",
"The closure type."
)]
#[document_parameters("The closure that takes owned values.")]
impl<'a, Brand, A, B, F>
BindDispatch<
'a,
Brand,
A,
B,
Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
Val,
> for F
where
Brand: Semimonad,
A: 'a,
B: 'a,
F: Fn(A) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
{
#[document_signature]
#[document_parameters("The monadic value.")]
#[document_returns("The result of binding.")]
#[document_examples]
fn dispatch(
self,
ma: Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
Brand::bind(ma, self)
}
}
#[document_type_parameters(
"The lifetime.",
"The borrow lifetime.",
"The brand.",
"The input type.",
"The output type.",
"The closure type."
)]
#[document_parameters("The closure that takes references.")]
impl<'a, 'b, Brand, A, B, F>
BindDispatch<
'a,
Brand,
A,
B,
&'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
Ref,
> for F
where
Brand: RefSemimonad,
A: 'a,
B: 'a,
F: Fn(&A) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
{
#[document_signature]
#[document_parameters("A reference to the monadic value.")]
#[document_returns("The result of binding.")]
#[document_examples]
fn dispatch(
self,
ma: &'b Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>),
) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
Brand::ref_bind(ma, self)
}
}
#[document_type_parameters(
"The lifetime of the values.",
"The higher-kinded type brand.",
"The input type.",
"The intermediate type.",
"The output type.",
"Marker type (`Val` or `Ref`), inferred from the closures."
)]
#[document_parameters("The closure pair implementing this dispatch.")]
pub trait ComposeKleisliDispatch<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a, B: 'a, C: 'a, Marker>
{
#[document_signature]
#[document_parameters("The input value.")]
#[document_returns("The result of composing f then g applied to the input.")]
#[document_examples]
fn dispatch(
self,
a: A,
) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>);
}
#[document_type_parameters(
"The lifetime of the values.",
"The higher-kinded type brand.",
"The input type.",
"The intermediate type.",
"The output type.",
"The first closure type.",
"The second closure type."
)]
#[document_parameters("The closure pair.")]
impl<'a, Brand, A, B, C, F, G> ComposeKleisliDispatch<'a, Brand, A, B, C, Val> for (F, G)
where
Brand: Semimonad,
A: 'a,
B: 'a,
C: 'a,
F: Fn(A) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
G: Fn(B) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
{
#[document_signature]
#[document_parameters("The input value.")]
#[document_returns("The composed result.")]
#[document_examples]
fn dispatch(
self,
a: A,
) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) {
Brand::bind(self.0(a), self.1)
}
}
#[document_type_parameters(
"The lifetime of the values.",
"The higher-kinded type brand.",
"The input type.",
"The intermediate type.",
"The output type.",
"The first closure type.",
"The second closure type."
)]
#[document_parameters("The closure pair.")]
impl<'a, Brand, A, B, C, F, G> ComposeKleisliDispatch<'a, Brand, A, B, C, Ref> for (F, G)
where
Brand: RefSemimonad,
A: 'a,
B: 'a,
C: 'a,
F: Fn(&A) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) + 'a,
G: Fn(&B) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) + 'a,
{
#[document_signature]
#[document_parameters("The input value.")]
#[document_returns("The composed result.")]
#[document_examples]
fn dispatch(
self,
a: A,
) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) {
Brand::ref_bind(&(self.0(&a)), self.1)
}
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the values.",
"The higher-kinded type brand.",
"The input type.",
"The intermediate type.",
"The output type.",
"Marker type, inferred from the closures."
)]
#[document_parameters("A tuple of (first arrow, second arrow).", "The input value.")]
#[document_returns("The result of applying f then g.")]
#[document_examples]
pub fn compose_kleisli<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a, B: 'a, C: 'a, Marker>(
fg: impl ComposeKleisliDispatch<'a, Brand, A, B, C, Marker>,
a: A,
) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>) {
fg.dispatch(a)
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the values.",
"The higher-kinded type brand.",
"The input type.",
"The intermediate type.",
"The output type.",
"The second arrow type (`B -> Of<C>`).",
"The first arrow type (`A -> Of<B>`).",
"Marker type, inferred from the closures."
)]
#[document_parameters("A tuple of (second arrow, first arrow).", "The input value.")]
#[document_returns("The result of applying g then f.")]
#[document_examples]
pub fn compose_kleisli_flipped<
'a,
Brand: Kind_cdc7cd43dac7585f,
A: 'a,
B: 'a,
C: 'a,
F,
G,
Marker,
>(
gf: (F, G),
a: A,
) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, C>)
where
(G, F): ComposeKleisliDispatch<'a, Brand, A, B, C, Marker>, {
ComposeKleisliDispatch::dispatch((gf.1, gf.0), a)
}
#[document_type_parameters(
"The lifetime of the values.",
"The brand of the monad.",
"The type of the value(s) inside the inner layer.",
"Dispatch marker type, inferred automatically. Either [`Val`](crate::dispatch::Val) or [`Ref`](crate::dispatch::Ref)."
)]
#[document_parameters("The container implementing this dispatch.")]
pub trait JoinDispatch<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a, Marker> {
#[document_signature]
#[document_returns("A container with one layer of nesting removed.")]
#[document_examples]
fn dispatch(self) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>);
}
#[document_type_parameters("The lifetime.", "The brand.", "The inner element type.")]
#[document_parameters("The nested monadic value.")]
impl<'a, Brand, A> JoinDispatch<'a, Brand, A, Val> for Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)>)
where
Brand: Semimonad,
A: 'a,
{
#[document_signature]
#[document_returns("A container with one layer of nesting removed.")]
#[document_examples]
fn dispatch(self) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
Brand::bind(self, |ma| ma)
}
}
#[document_type_parameters("The lifetime.", "The brand.", "The inner element type.")]
#[document_parameters("A reference to the nested monadic value.")]
impl<'a, Brand, A> JoinDispatch<'a, Brand, A, Ref> for &Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>)>)
where
Brand: RefSemimonad,
A: 'a,
Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>): Clone,
{
#[document_signature]
#[document_returns("A container with one layer of nesting removed.")]
#[document_examples]
fn dispatch(self) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
Brand::ref_bind(self, |ma| ma.clone())
}
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the values.",
"The container type (owned or borrowed). Brand is inferred from this.",
"The type of the value inside the monad.",
"The type of the result.",
"Dispatch marker type, inferred automatically."
)]
#[document_parameters(
"The monadic value (owned for Val, borrowed for Ref).",
"The function to apply to the value."
)]
#[document_returns("The result of sequencing the computation.")]
#[document_examples]
pub fn bind<'a, FA, A: 'a, B: 'a, Marker>(
ma: FA,
f: impl BindDispatch<'a, <FA as InferableBrand_cdc7cd43dac7585f>::Brand, A, B, FA, Marker>,
) -> Apply!(<<FA as InferableBrand!(type Of<'a, A: 'a>: 'a;)>::Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
where
FA: InferableBrand_cdc7cd43dac7585f, {
f.dispatch(ma)
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the values.",
"The container type (owned or borrowed). Brand is inferred from this.",
"The input element type.",
"The output element type.",
"Dispatch marker type, inferred automatically."
)]
#[document_parameters(
"The function to apply to each element.",
"The monadic value (owned for Val, borrowed for Ref)."
)]
#[document_returns("The result of binding the function over the value.")]
#[document_examples]
pub fn bind_flipped<'a, FA, A: 'a, B: 'a, Marker>(
f: impl BindDispatch<'a, <FA as InferableBrand_cdc7cd43dac7585f>::Brand, A, B, FA, Marker>,
ma: FA,
) -> Apply!(<<FA as InferableBrand!(type Of<'a, A: 'a>: 'a;)>::Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>)
where
FA: InferableBrand_cdc7cd43dac7585f, {
f.dispatch(ma)
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the values.",
"The container type (owned or borrowed). Brand is inferred from this.",
"The type of the value(s) inside the inner layer.",
"Dispatch marker type, inferred automatically."
)]
#[document_parameters("The nested monadic value (owned or borrowed).")]
#[document_returns("A container with one layer of nesting removed.")]
#[document_examples]
pub fn join<'a, FA, A: 'a, Marker>(
mma: FA
) -> <<FA as InferableBrand_cdc7cd43dac7585f>::Brand as Kind_cdc7cd43dac7585f>::Of<'a, A>
where
FA: InferableBrand_cdc7cd43dac7585f
+ JoinDispatch<'a, <FA as InferableBrand_cdc7cd43dac7585f>::Brand, A, Marker>, {
mma.dispatch()
}
pub mod explicit {
use super::*;
#[document_signature]
#[document_type_parameters(
"The lifetime of the values.",
"The brand of the monad.",
"The type of the value inside the monad.",
"The type of the result.",
"The container type (owned or borrowed), inferred from the argument.",
"Dispatch marker type, inferred automatically."
)]
#[document_parameters(
"The monadic value (owned for Val, borrowed for Ref).",
"The function to apply to the value."
)]
#[document_returns("The result of sequencing the computation.")]
#[document_examples]
pub fn bind<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a, B: 'a, FA, Marker>(
ma: FA,
f: impl BindDispatch<'a, Brand, A, B, FA, Marker>,
) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
f.dispatch(ma)
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the values.",
"The higher-kinded type brand.",
"The input element type.",
"The output element type.",
"The container type (owned or borrowed), inferred from the argument.",
"Marker type, inferred from the closure."
)]
#[document_parameters(
"The function to apply to each element.",
"The monadic value to bind over (owned for Val, borrowed for Ref)."
)]
#[document_returns("The result of binding the function over the value.")]
#[document_examples]
pub fn bind_flipped<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a, B: 'a, FA, Marker>(
f: impl BindDispatch<'a, Brand, A, B, FA, Marker>,
ma: FA,
) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, B>) {
f.dispatch(ma)
}
#[document_signature]
#[document_type_parameters(
"The lifetime of the values.",
"The brand of the monad.",
"The type of the value(s) inside the inner layer.",
"Dispatch marker type, inferred automatically."
)]
#[document_parameters("The nested monadic value (owned or borrowed).")]
#[document_returns("A container with one layer of nesting removed.")]
#[document_examples]
pub fn join<'a, Brand: Kind_cdc7cd43dac7585f, A: 'a, Marker>(
mma: impl JoinDispatch<'a, Brand, A, Marker>
) -> Apply!(<Brand as Kind!( type Of<'a, T: 'a>: 'a; )>::Of<'a, A>) {
mma.dispatch()
}
}
}
pub use inner::*;