From 8d74cd6f3fe91bea98746be2c305a3acdd5093b3 Mon Sep 17 00:00:00 2001 From: timofey <tim@ongoteam.yaconnect.com> Date: Mon, 24 Apr 2023 23:54:49 +0000 Subject: [PATCH] flow docs --- src/flow.rs | 2 ++ src/flow/traversible.rs | 28 ++++++++++++++++++++++++++++ src/func.rs | 6 ++++++ src/std.rs | 10 ++++++++-- 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/flow.rs b/src/flow.rs index 92e6c1d..ed64186 100644 --- a/src/flow.rs +++ b/src/flow.rs @@ -1 +1,3 @@ +//! Data structures and algorithms, independent of [crate::core] concepts. + pub mod traversible; diff --git a/src/flow/traversible.rs b/src/flow/traversible.rs index 8f0ed80..b7fd998 100644 --- a/src/flow/traversible.rs +++ b/src/flow/traversible.rs @@ -1,9 +1,14 @@ +//! Traversible binary trees. + use std::rc::Rc; use crate::func::*; +/// Result returned by [`Comparator::pick_smaller`]. +#[derive(Debug, PartialEq)] pub enum Comparison { L, + /// Compared values were equal. E, R, } @@ -12,10 +17,33 @@ fn and(left: bool, right: bool) -> bool { left && right } +/// Returns [`Comparison`] saying which value is smaller. +/// +/// ```rust +/// # use radn_rs::flow::traversible::*; +/// assert_eq!(DefaultComparator.pick_smaller(&1, &3), Comparison::L); +/// assert_eq!(DefaultComparator.pick_smaller(&2, &2), Comparison::E); +/// assert_eq!(DefaultComparator.pick_smaller(&3, &1), Comparison::R); +/// ``` pub trait Comparator<A> { fn pick_smaller(&self, kl: &A, kr: &A) -> Comparison; } +/// Implementation of a [Comparator] relying on [`PartialOrd`]. +pub struct DefaultComparator; + +impl<A: PartialOrd> Comparator<A> for DefaultComparator { + fn pick_smaller(&self, kl: &A, kr: &A) -> Comparison { + if kl < kr { + Comparison::L + } else if kr < kl { + Comparison::R + } else { + Comparison::E + } + } +} + pub type Split<'a, T, A, D> = ( Rc<dyn TraversibleBinaryTree<'a, T, A, D>>, Rc<dyn TraversibleBinaryTree<'a, T, A, D>>, diff --git a/src/func.rs b/src/func.rs index 35c15a4..ac90710 100644 --- a/src/func.rs +++ b/src/func.rs @@ -20,6 +20,7 @@ pub mod tests; /// /// <https://hackage.haskell.org/package/base-4.18.0.0/docs/Data-Functor.html> pub trait WeakFunctor { + /// Type of the wrapped value. type F<'a, A: 'a>: 'a where Self: 'a; @@ -233,10 +234,15 @@ pub trait LocalFunctor: WeakFunctor { Self: 'a; } +/// Represents a (collection of) [Monad]\(s) that can hold any type of error. pub trait MonadFailAny { + /// [`MonadFail`] for a specific error type. type W<E>: MonadFail<E>; } +/// Represents a (collection of) [Monad]\(s), +/// wrapped values of which are interchangeable with another [Monad]'s +/// wrapped [Result]s. pub trait MonadFailOver<T: Monad>: MonadFailAny { fn unstuff<'a, A: 'a, E: 'a>( wa: <Self::W<E> as WeakFunctor>::F<'a, A>, diff --git a/src/std.rs b/src/std.rs index 5ce6f46..30fa0ac 100644 --- a/src/std.rs +++ b/src/std.rs @@ -36,13 +36,19 @@ impl<S: Serializable> ExtSerializable for S { } } -pub trait ExtContext: Context { +/// Extention trait for simpler conversion between [`Context::T`] and [`Context::Fallible`]. +/// +/// Until either Rust type system or [`crate::func`] take serious changes, +/// this is the preferred way to switch between [Wrapped] and [fallible]. +pub trait FallibleContext: Context { + /// Convert a fallible wrapped into a wrapped result. fn unstuff<'a, A: 'a, E: 'a>( wa: <<Self::Fallible as MonadFailAny>::W<E> as WeakFunctor>::F<'a, A>, ) -> <Self::T as WeakFunctor>::F<'a, Result<A, E>> where Self: 'a; + /// Convert a wrapped result into a fallible wrapped. fn stuff<'a, A: 'a, E: 'a>( fa: <Self::T as WeakFunctor>::F<'a, Result<A, E>>, ) -> <<Self::Fallible as MonadFailAny>::W<E> as WeakFunctor>::F<'a, A> @@ -50,7 +56,7 @@ pub trait ExtContext: Context { Self: 'a; } -impl<Ctx: Context> ExtContext for Ctx { +impl<Ctx: Context> FallibleContext for Ctx { fn unstuff<'a, A: 'a, E: 'a>( wa: <<Self::Fallible as MonadFailAny>::W<E> as WeakFunctor>::F<'a, A>, ) -> <Self::T as WeakFunctor>::F<'a, Result<A, E>>