parent
b05326089d
commit
73e9b9efb3
16
src/func.rs
16
src/func.rs
@ -9,18 +9,20 @@
|
|||||||
|
|
||||||
pub mod classes;
|
pub mod classes;
|
||||||
pub mod clone_func;
|
pub mod clone_func;
|
||||||
|
mod controlflow;
|
||||||
pub mod copy_func;
|
pub mod copy_func;
|
||||||
pub mod derivations;
|
pub mod derivations;
|
||||||
mod istate;
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod test_suite;
|
pub mod test_suite;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod tests;
|
pub mod tests;
|
||||||
|
|
||||||
pub use self::istate::IState;
|
pub use std::ops::ControlFlow;
|
||||||
use self::istate::IStateClass;
|
|
||||||
pub use radn_derive::{CovariantFunctor, SharedFunctor};
|
pub use radn_derive::{CovariantFunctor, SharedFunctor};
|
||||||
|
|
||||||
|
pub use self::controlflow::ControlFlowClass;
|
||||||
|
|
||||||
/// Part of Haskell's `Functor f` responsible to use `f a`.
|
/// Part of Haskell's `Functor f` responsible to use `f a`.
|
||||||
///
|
///
|
||||||
/// <https://hackage.haskell.org/package/base-4.18.0.0/docs/Data-Functor.html>
|
/// <https://hackage.haskell.org/package/base-4.18.0.0/docs/Data-Functor.html>
|
||||||
@ -177,7 +179,7 @@ pub trait Monad: Applicative {
|
|||||||
/// On practice, you shouldn't be using [`Monad::bind`]/[`Pure::pure`]/[`Functor::fmap`] here.
|
/// On practice, you shouldn't be using [`Monad::bind`]/[`Pure::pure`]/[`Functor::fmap`] here.
|
||||||
fn ibind<'a, A: 'a, B: 'a>(
|
fn ibind<'a, A: 'a, B: 'a>(
|
||||||
a: A,
|
a: A,
|
||||||
f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>,
|
f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>,
|
||||||
) -> Self::F<'a, B>
|
) -> Self::F<'a, B>
|
||||||
where
|
where
|
||||||
Self: 'a;
|
Self: 'a;
|
||||||
@ -222,11 +224,13 @@ pub trait Alternative: Applicative {
|
|||||||
/// Represents wrapped results which are instantly available.
|
/// Represents wrapped results which are instantly available.
|
||||||
pub trait LocalFunctor: WeakFunctor {
|
pub trait LocalFunctor: WeakFunctor {
|
||||||
/// Extract iteration state, if successful.
|
/// Extract iteration state, if successful.
|
||||||
fn unstuff<'a, A: 'a, B: 'a>(state: Self::F<'a, IState<A, B>>) -> IState<A, Self::F<'a, B>>
|
fn unstuff<'a, A: 'a, B: 'a>(
|
||||||
|
state: Self::F<'a, ControlFlow<B, A>>,
|
||||||
|
) -> ControlFlow<Self::F<'a, B>, A>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
{
|
{
|
||||||
Self::stuff::<_, IStateClass<A>>(state)
|
Self::stuff::<_, ControlFlowClass<A>>(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stuff wrapped result into another functor.
|
/// Stuff wrapped result into another functor.
|
||||||
|
@ -101,7 +101,7 @@ impl<U: Monad, V: Monad + LocalFunctor> Monad for CompositionClass<U, V> {
|
|||||||
|
|
||||||
fn ibind<'a, A: 'a, B: 'a>(
|
fn ibind<'a, A: 'a, B: 'a>(
|
||||||
a: A,
|
a: A,
|
||||||
mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>,
|
mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>,
|
||||||
) -> Self::F<'a, B>
|
) -> Self::F<'a, B>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
@ -132,7 +132,9 @@ impl<E, U: Monad, V: MonadFail<E> + LocalFunctor> MonadFail<E> for CompositionCl
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<U: LocalFunctor + Functor, V: LocalFunctor> LocalFunctor for CompositionClass<U, V> {
|
impl<U: LocalFunctor + Functor, V: LocalFunctor> LocalFunctor for CompositionClass<U, V> {
|
||||||
fn unstuff<'a, A: 'a, B: 'a>(state: Self::F<'a, IState<A, B>>) -> IState<A, Self::F<'a, B>>
|
fn unstuff<'a, A: 'a, B: 'a>(
|
||||||
|
state: Self::F<'a, ControlFlow<B, A>>,
|
||||||
|
) -> ControlFlow<Self::F<'a, B>, A>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
{
|
{
|
||||||
|
@ -89,7 +89,7 @@ impl Monad for FutureClass {
|
|||||||
|
|
||||||
fn ibind<'a, A: 'a, B: 'a>(
|
fn ibind<'a, A: 'a, B: 'a>(
|
||||||
mut a: A,
|
mut a: A,
|
||||||
mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>,
|
mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>,
|
||||||
) -> Self::F<'a, B>
|
) -> Self::F<'a, B>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
@ -97,8 +97,8 @@ impl Monad for FutureClass {
|
|||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
loop {
|
loop {
|
||||||
match f(a).await {
|
match f(a).await {
|
||||||
IState::Pending(next_a) => a = next_a,
|
ControlFlow::Continue(next_a) => a = next_a,
|
||||||
IState::Done(b) => return b,
|
ControlFlow::Break(b) => return b,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -90,15 +90,15 @@ impl Monad for LazyClass {
|
|||||||
|
|
||||||
fn ibind<'a, A: 'a, B: 'a>(
|
fn ibind<'a, A: 'a, B: 'a>(
|
||||||
mut a: A,
|
mut a: A,
|
||||||
mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>,
|
mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>,
|
||||||
) -> Self::F<'a, B>
|
) -> Self::F<'a, B>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
{
|
{
|
||||||
Box::new(move || loop {
|
Box::new(move || loop {
|
||||||
match f(a)() {
|
match f(a)() {
|
||||||
IState::Pending(next_a) => a = next_a,
|
ControlFlow::Continue(next_a) => a = next_a,
|
||||||
IState::Done(b) => return b,
|
ControlFlow::Break(b) => return b,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -94,15 +94,15 @@ impl Monad for OptionClass {
|
|||||||
|
|
||||||
fn ibind<'a, A: 'a, B: 'a>(
|
fn ibind<'a, A: 'a, B: 'a>(
|
||||||
mut a: A,
|
mut a: A,
|
||||||
mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>,
|
mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>,
|
||||||
) -> Self::F<'a, B>
|
) -> Self::F<'a, B>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
{
|
{
|
||||||
loop {
|
loop {
|
||||||
match f(a)? {
|
match f(a)? {
|
||||||
IState::Pending(next_a) => a = next_a,
|
ControlFlow::Continue(next_a) => a = next_a,
|
||||||
IState::Done(b) => return Self::pure(b),
|
ControlFlow::Break(b) => return Self::pure(b),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,14 +113,16 @@ impl Monad for OptionClass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LocalFunctor for OptionClass {
|
impl LocalFunctor for OptionClass {
|
||||||
fn unstuff<'a, A: 'a, B: 'a>(state: Self::F<'a, IState<A, B>>) -> IState<A, Self::F<'a, B>>
|
fn unstuff<'a, A: 'a, B: 'a>(
|
||||||
|
state: Self::F<'a, ControlFlow<B, A>>,
|
||||||
|
) -> ControlFlow<Self::F<'a, B>, A>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
{
|
{
|
||||||
match state {
|
match state {
|
||||||
Some(IState::Pending(a)) => IState::Pending(a),
|
Some(ControlFlow::Continue(a)) => ControlFlow::Continue(a),
|
||||||
Some(IState::Done(b)) => IState::Done(Some(b)),
|
Some(ControlFlow::Break(b)) => ControlFlow::Break(Some(b)),
|
||||||
None => IState::Done(None),
|
None => ControlFlow::Break(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,15 +115,15 @@ impl<E> Monad for ResultClass<E> {
|
|||||||
|
|
||||||
fn ibind<'a, A: 'a, B: 'a>(
|
fn ibind<'a, A: 'a, B: 'a>(
|
||||||
mut a: A,
|
mut a: A,
|
||||||
mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>,
|
mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>,
|
||||||
) -> Self::F<'a, B>
|
) -> Self::F<'a, B>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
{
|
{
|
||||||
loop {
|
loop {
|
||||||
match f(a)? {
|
match f(a)? {
|
||||||
IState::Pending(next_a) => a = next_a,
|
ControlFlow::Continue(next_a) => a = next_a,
|
||||||
IState::Done(b) => return Self::pure(b),
|
ControlFlow::Break(b) => return Self::pure(b),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,14 +137,16 @@ impl<E> Monad for ResultClass<E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<E> LocalFunctor for ResultClass<E> {
|
impl<E> LocalFunctor for ResultClass<E> {
|
||||||
fn unstuff<'a, A: 'a, B: 'a>(state: Self::F<'a, IState<A, B>>) -> IState<A, Self::F<'a, B>>
|
fn unstuff<'a, A: 'a, B: 'a>(
|
||||||
|
state: Self::F<'a, ControlFlow<B, A>>,
|
||||||
|
) -> ControlFlow<Self::F<'a, B>, A>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
{
|
{
|
||||||
match state {
|
match state {
|
||||||
Ok(IState::Pending(a)) => IState::Pending(a),
|
Ok(ControlFlow::Continue(a)) => ControlFlow::Continue(a),
|
||||||
Ok(IState::Done(b)) => IState::Done(Ok(b)),
|
Ok(ControlFlow::Break(b)) => ControlFlow::Break(Ok(b)),
|
||||||
Err(e) => IState::Done(Err(e)),
|
Err(e) => ControlFlow::Break(Err(e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,15 +82,15 @@ impl Monad for SoloClass {
|
|||||||
|
|
||||||
fn ibind<'a, A: 'a, B: 'a>(
|
fn ibind<'a, A: 'a, B: 'a>(
|
||||||
mut a: A,
|
mut a: A,
|
||||||
mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>,
|
mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>,
|
||||||
) -> Self::F<'a, B>
|
) -> Self::F<'a, B>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
{
|
{
|
||||||
loop {
|
loop {
|
||||||
match f(a) {
|
match f(a) {
|
||||||
IState::Pending(next_a) => a = next_a,
|
ControlFlow::Continue(next_a) => a = next_a,
|
||||||
IState::Done(b) => return b,
|
ControlFlow::Break(b) => return b,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,7 +101,9 @@ impl Monad for SoloClass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LocalFunctor for SoloClass {
|
impl LocalFunctor for SoloClass {
|
||||||
fn unstuff<'a, A: 'a, B: 'a>(state: Self::F<'a, IState<A, B>>) -> IState<A, Self::F<'a, B>>
|
fn unstuff<'a, A: 'a, B: 'a>(
|
||||||
|
state: Self::F<'a, ControlFlow<B, A>>,
|
||||||
|
) -> ControlFlow<Self::F<'a, B>, A>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
{
|
{
|
||||||
|
@ -226,15 +226,15 @@ impl Monad for StacklessClass {
|
|||||||
|
|
||||||
fn ibind<'a, A: 'a, B: 'a>(
|
fn ibind<'a, A: 'a, B: 'a>(
|
||||||
a: A,
|
a: A,
|
||||||
mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>,
|
mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>,
|
||||||
) -> Self::F<'a, B>
|
) -> Self::F<'a, B>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
{
|
{
|
||||||
Self::pure(a).bind(move |a| {
|
Self::pure(a).bind(move |a| {
|
||||||
f(a).bind(|state| match state {
|
f(a).bind(|state| match state {
|
||||||
IState::Pending(a) => Self::ibind(a, f),
|
ControlFlow::Continue(a) => Self::ibind(a, f),
|
||||||
IState::Done(b) => Self::pure(b),
|
ControlFlow::Break(b) => Self::pure(b),
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
30
src/func/controlflow.rs
Normal file
30
src/func/controlflow.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub struct ControlFlowClass<C>(ControlFlow<(), C>);
|
||||||
|
|
||||||
|
impl<C> WeakFunctor for ControlFlowClass<C> {
|
||||||
|
type F<'a, A: 'a> = ControlFlow<A, C>
|
||||||
|
where
|
||||||
|
Self: 'a;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C> Functor for ControlFlowClass<C> {
|
||||||
|
fn fmap<'a, A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B>
|
||||||
|
where
|
||||||
|
Self: 'a,
|
||||||
|
{
|
||||||
|
match fa {
|
||||||
|
ControlFlow::Continue(c) => ControlFlow::Continue(c),
|
||||||
|
ControlFlow::Break(a) => ControlFlow::Break(f(a)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C> Pure for ControlFlowClass<C> {
|
||||||
|
fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A>
|
||||||
|
where
|
||||||
|
Self: 'a,
|
||||||
|
{
|
||||||
|
ControlFlow::Break(a)
|
||||||
|
}
|
||||||
|
}
|
@ -1,44 +0,0 @@
|
|||||||
use super::*;
|
|
||||||
|
|
||||||
/// Represents iteration state. Used in [`Monad::ibind`].
|
|
||||||
///
|
|
||||||
/// [`IState<P, D>`] is isomorphic to [`Result<D, P>`].
|
|
||||||
pub enum IState<P, D> {
|
|
||||||
/// Loop running.
|
|
||||||
///
|
|
||||||
/// Isomorphic to [`Result::Err`].
|
|
||||||
Pending(P),
|
|
||||||
/// Loop finished.
|
|
||||||
///
|
|
||||||
/// Isomorphic to [`Result::Ok`].
|
|
||||||
Done(D),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct IStateClass<P>(P);
|
|
||||||
|
|
||||||
impl<P> WeakFunctor for IStateClass<P> {
|
|
||||||
type F<'a, A: 'a> = IState<P, A>
|
|
||||||
where
|
|
||||||
Self: 'a;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P> Functor for IStateClass<P> {
|
|
||||||
fn fmap<'a, A: 'a, B: 'a>(f: impl 'a + FnOnce(A) -> B, fa: Self::F<'a, A>) -> Self::F<'a, B>
|
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
{
|
|
||||||
match fa {
|
|
||||||
IState::Pending(p) => IState::Pending(p),
|
|
||||||
IState::Done(d) => IState::Done(f(d)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P> Pure for IStateClass<P> {
|
|
||||||
fn pure<'a, A: 'a>(a: A) -> Self::F<'a, A>
|
|
||||||
where
|
|
||||||
Self: 'a,
|
|
||||||
{
|
|
||||||
IState::Done(a)
|
|
||||||
}
|
|
||||||
}
|
|
@ -158,17 +158,17 @@ impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> ExtStack<'a, Ctx, A> for St
|
|||||||
}
|
}
|
||||||
fn vec(self) -> StackVecWrapped<'a, Ctx, A> {
|
fn vec(self) -> StackVecWrapped<'a, Ctx, A> {
|
||||||
Ctx::T::ibind((vec![], self), |(mut vec, stack)| match stack {
|
Ctx::T::ibind((vec![], self), |(mut vec, stack)| match stack {
|
||||||
Nullable::Null(_) => Ctx::T::pure(IState::Done(Ok(vec))),
|
Nullable::Null(_) => Ctx::T::pure(ControlFlow::Break(Ok(vec))),
|
||||||
Nullable::NotNull(point) => Ctx::T::fmap(
|
Nullable::NotNull(point) => Ctx::T::fmap(
|
||||||
|resolved| {
|
|resolved| {
|
||||||
let node = match resolved {
|
let node = match resolved {
|
||||||
Ok(node) => node,
|
Ok(node) => node,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
return IState::Done(Err(error));
|
return ControlFlow::Break(Err(error));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
vec.push(node.element.clone());
|
vec.push(node.element.clone());
|
||||||
IState::Pending((vec, node.rest.clone()))
|
ControlFlow::Continue((vec, node.rest.clone()))
|
||||||
},
|
},
|
||||||
point.resolve(),
|
point.resolve(),
|
||||||
),
|
),
|
||||||
|
@ -165,7 +165,7 @@ impl Monad for TracedClass {
|
|||||||
|
|
||||||
fn ibind<'a, A: 'a, B: 'a>(
|
fn ibind<'a, A: 'a, B: 'a>(
|
||||||
mut a: A,
|
mut a: A,
|
||||||
mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>,
|
mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>,
|
||||||
) -> Self::F<'a, B>
|
) -> Self::F<'a, B>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
@ -175,8 +175,8 @@ impl Monad for TracedClass {
|
|||||||
let fa = f(a);
|
let fa = f(a);
|
||||||
t = fa.t.after(t);
|
t = fa.t.after(t);
|
||||||
match fa.a {
|
match fa.a {
|
||||||
IState::Pending(next_a) => a = next_a,
|
ControlFlow::Continue(next_a) => a = next_a,
|
||||||
IState::Done(b) => return b.with_trace(t),
|
ControlFlow::Break(b) => return b.with_trace(t),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,7 @@ impl Monad for CountedClass {
|
|||||||
|
|
||||||
fn ibind<'a, A: 'a, B: 'a>(
|
fn ibind<'a, A: 'a, B: 'a>(
|
||||||
mut a: A,
|
mut a: A,
|
||||||
mut f: impl 'a + FnMut(A) -> Self::F<'a, IState<A, B>>,
|
mut f: impl 'a + FnMut(A) -> Self::F<'a, ControlFlow<B, A>>,
|
||||||
) -> Self::F<'a, B>
|
) -> Self::F<'a, B>
|
||||||
where
|
where
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
@ -157,8 +157,8 @@ impl Monad for CountedClass {
|
|||||||
let fa = f(a);
|
let fa = f(a);
|
||||||
n += fa.n;
|
n += fa.n;
|
||||||
match fa.a {
|
match fa.a {
|
||||||
IState::Pending(next_a) => a = next_a,
|
ControlFlow::Continue(next_a) => a = next_a,
|
||||||
IState::Done(b) => return b.with_count(n),
|
ControlFlow::Break(b) => return b.with_count(n),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user