BinaryTreesAvl
This commit is contained in:
parent
beefedaf2b
commit
f5cbf65df9
@ -1,20 +1,21 @@
|
|||||||
|
mod avl;
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::func::*;
|
use crate::{flow::comparator::*, func::*};
|
||||||
|
|
||||||
use super::comparator::Comparator;
|
|
||||||
|
|
||||||
pub type NodeRc<'a, BT> = Rc<<BT as BinaryTrees<'a>>::Node>;
|
|
||||||
pub type ReferenceRc<'a, BT> = Rc<<BT as BinaryTrees<'a>>::Reference>;
|
|
||||||
pub type TreeRc<'a, BT> = Rc<<BT as BinaryTrees<'a>>::Tree>;
|
|
||||||
pub type KeyRc<'a, BT> = Rc<<BT as BinaryTrees<'a>>::Key>;
|
pub type KeyRc<'a, BT> = Rc<<BT as BinaryTrees<'a>>::Key>;
|
||||||
|
|
||||||
pub type Split<'a, BT> = (TreeRc<'a, BT>, TreeRc<'a, BT>, KeyRc<'a, BT>);
|
pub type Split<'a, BT> = (
|
||||||
pub type KeySplit<'a, BT> = (TreeRc<'a, BT>, TreeRc<'a, BT>);
|
<BT as BinaryTrees<'a>>::Tree,
|
||||||
|
<BT as BinaryTrees<'a>>::Tree,
|
||||||
|
KeyRc<'a, BT>,
|
||||||
|
);
|
||||||
|
pub type KeySplit<'a, BT> = (<BT as BinaryTrees<'a>>::Tree, <BT as BinaryTrees<'a>>::Tree);
|
||||||
|
|
||||||
pub type BTWrap<'a, BT, A> = Wrap<'a, A, <BT as BinaryTrees<'a>>::T>;
|
pub type BTWrap<'a, BT, A> = Wrap<'a, A, <BT as BinaryTrees<'a>>::T>;
|
||||||
|
|
||||||
pub trait BinaryTrees<'a>: 'a {
|
pub trait BinaryTrees<'a>: 'a + Clone {
|
||||||
type Node: 'a;
|
type Node: 'a;
|
||||||
type Reference: 'a;
|
type Reference: 'a;
|
||||||
type Tree: 'a;
|
type Tree: 'a;
|
||||||
@ -25,24 +26,188 @@ pub trait BinaryTrees<'a>: 'a {
|
|||||||
|
|
||||||
fn comparator(&self) -> &Self::Comparator;
|
fn comparator(&self) -> &Self::Comparator;
|
||||||
fn split(&self, node: &Self::Node) -> Split<'a, Self>;
|
fn split(&self, node: &Self::Node) -> Split<'a, Self>;
|
||||||
fn tree_of(&self, node: Self::Node) -> BTWrap<'a, Self, TreeRc<'a, Self>>;
|
fn tree_of(&self, node: Self::Node) -> BTWrap<'a, Self, Self::Tree>;
|
||||||
fn resolve(&self, reference: &Self::Reference) -> BTWrap<'a, Self, NodeRc<'a, Self>>;
|
fn resolve(&self, reference: &Self::Reference) -> BTWrap<'a, Self, Self::Node>;
|
||||||
fn equal(&self, rhs: &Self::Reference, lhs: &Self::Reference) -> bool;
|
fn equal(&self, rhs: &Self::Reference, lhs: &Self::Reference) -> bool;
|
||||||
fn refer(&self, tree: &Self::Tree) -> Option<ReferenceRc<'a, Self>>;
|
fn refer(&self, tree: &Self::Tree) -> Option<Self::Reference>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait BinaryTreesMutable<'a>: BinaryTrees<'a> {
|
pub trait BinaryTreesMutable<'a>: BinaryTrees<'a> {
|
||||||
fn empty(&self) -> Self::Tree;
|
fn empty(&self) -> Self::Tree;
|
||||||
|
|
||||||
fn join_key(
|
fn join_key(
|
||||||
&self,
|
self,
|
||||||
tl: Self::Tree,
|
tl: Self::Tree,
|
||||||
key: KeyRc<'a, Self>,
|
key: KeyRc<'a, Self>,
|
||||||
tr: Self::Tree,
|
tr: Self::Tree,
|
||||||
) -> BTWrap<'a, Self, NodeRc<'a, Self>>;
|
) -> BTWrap<'a, Self, Self::Node>;
|
||||||
fn join(&self, tl: Self::Tree, tr: Self::Tree) -> BTWrap<'a, Self, TreeRc<'a, Self>>;
|
|
||||||
fn split_key(
|
fn join_key_tree(
|
||||||
|
self,
|
||||||
|
tl: Self::Tree,
|
||||||
|
key: KeyRc<'a, Self>,
|
||||||
|
tr: Self::Tree,
|
||||||
|
) -> BTWrap<'a, Self, Self::Tree> {
|
||||||
|
<Self::T as Monad>::bind(self.clone().join_key(tl, key, tr), move |n| self.tree_of(n))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn join(&self, tl: Self::Tree, tr: Self::Tree) -> BTWrap<'a, Self, Self::Tree> {
|
||||||
|
let Some(rl) = self.refer(&tl) else {
|
||||||
|
return <Self::T as Pure>::pure(tr)
|
||||||
|
};
|
||||||
|
let Some(rr) = self.refer(&tr) else {
|
||||||
|
return <Self::T as Pure>::pure(tl)
|
||||||
|
};
|
||||||
|
let ctx = self.clone();
|
||||||
|
<Self::T as Monad>::join(<Self::T as ApplicativeLA2>::la2(
|
||||||
|
move |nl, nr| {
|
||||||
|
let (tll, tlr, kl) = ctx.split(&nl);
|
||||||
|
let (trl, trr, kr) = ctx.split(&nr);
|
||||||
|
let ft = ctx.join(tlr, trl);
|
||||||
|
let ft = {
|
||||||
|
let ctx = ctx.clone();
|
||||||
|
<Self::T as Monad>::bind(ft, move |t| ctx.join_key_tree(tll, kl, t))
|
||||||
|
};
|
||||||
|
let ft = {
|
||||||
|
let ctx = ctx.clone();
|
||||||
|
<Self::T as Monad>::bind(ft, move |t| ctx.join_key_tree(t, kr, trr))
|
||||||
|
};
|
||||||
|
ft
|
||||||
|
},
|
||||||
|
self.resolve(&rl),
|
||||||
|
self.resolve(&rr),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn split_key_empty(
|
||||||
&self,
|
&self,
|
||||||
tree: Self::Tree,
|
tree: Self::Tree,
|
||||||
key: KeyRc<'a, Self>,
|
key: KeyRc<'a, Self>,
|
||||||
) -> BTWrap<'a, Self, KeySplit<'a, Self>>;
|
) -> BTWrap<'a, Self, KeySplit<'a, Self>>;
|
||||||
|
|
||||||
|
fn split_key_node(
|
||||||
|
self,
|
||||||
|
node: Self::Node,
|
||||||
|
key: KeyRc<'a, Self>,
|
||||||
|
) -> BTWrap<'a, Self, KeySplit<'a, Self>> {
|
||||||
|
let (tl, tr, k) = self.split(&node);
|
||||||
|
match self.comparator().pick_smaller(&key, &k) {
|
||||||
|
Comparison::L => {
|
||||||
|
<Self::T as Monad>::bind(self.clone().split_key(tl, key), move |(tll, tlr)| {
|
||||||
|
<Self::T as Functor>::fmap(|t| (tll, t), self.join_key_tree(tlr, k, tr))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Comparison::E => <Self::T as Pure>::pure((tl, tr)),
|
||||||
|
Comparison::R => {
|
||||||
|
<Self::T as Monad>::bind(self.clone().split_key(tr, key), move |(trl, trr)| {
|
||||||
|
<Self::T as Functor>::fmap(|t| (t, trr), self.join_key_tree(tl, k, trl))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn split_key(
|
||||||
|
self,
|
||||||
|
tree: Self::Tree,
|
||||||
|
key: KeyRc<'a, Self>,
|
||||||
|
) -> BTWrap<'a, Self, KeySplit<'a, Self>> {
|
||||||
|
match self.refer(&tree) {
|
||||||
|
Some(reference) => <Self::T as Monad>::bind(self.resolve(&reference), |node| {
|
||||||
|
self.split_key_node(node, key)
|
||||||
|
}),
|
||||||
|
None => self.split_key_empty(tree, key),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add(self, tree: Self::Tree, key: KeyRc<'a, Self>) -> BTWrap<'a, Self, Self::Node> {
|
||||||
|
<Self::T as Monad>::bind(self.clone().split_key(tree, key.clone()), |(tl, tr)| {
|
||||||
|
self.join_key(tl, key, tr)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_tree(self, tree: Self::Tree, key: KeyRc<'a, Self>) -> BTWrap<'a, Self, Self::Tree> {
|
||||||
|
<Self::T as Monad>::bind(self.clone().add(tree, key), move |n| self.tree_of(n))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait BinaryTreesAvl<'a>: BinaryTrees<'a> {
|
||||||
|
fn height(&self, tree: &Self::Tree) -> u64;
|
||||||
|
|
||||||
|
fn leaf_height_error<T: 'a>(&self, height: u64) -> BTWrap<'a, Self, T>;
|
||||||
|
|
||||||
|
fn assume_node(&self, tree: &Self::Tree) -> BTWrap<'a, Self, Self::Node> {
|
||||||
|
match self.refer(tree) {
|
||||||
|
Some(reference) => self.resolve(&reference),
|
||||||
|
None => self.leaf_height_error(self.height(tree)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn join_key_unbalanced(
|
||||||
|
&self,
|
||||||
|
tl: Self::Tree,
|
||||||
|
key: KeyRc<'a, Self>,
|
||||||
|
tr: Self::Tree,
|
||||||
|
) -> BTWrap<'a, Self, Self::Node>;
|
||||||
|
|
||||||
|
fn join_key_balanced_tree(
|
||||||
|
self,
|
||||||
|
tl: Self::Tree,
|
||||||
|
key: KeyRc<'a, Self>,
|
||||||
|
tr: Self::Tree,
|
||||||
|
) -> BTWrap<'a, Self, Self::Tree> {
|
||||||
|
<Self::T as Monad>::bind(self.clone().join_key_balanced(tl, key, tr), move |node| {
|
||||||
|
self.tree_of(node)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn join_key_balanced(
|
||||||
|
self,
|
||||||
|
tl: Self::Tree,
|
||||||
|
key: KeyRc<'a, Self>,
|
||||||
|
tr: Self::Tree,
|
||||||
|
) -> BTWrap<'a, Self, Self::Node> {
|
||||||
|
let (lh, rh) = (self.height(&tl), self.height(&tr));
|
||||||
|
match (lh.saturating_sub(rh), rh.saturating_sub(lh)) {
|
||||||
|
(0, 0) | (0, 1) | (1, 0) => self.join_key_unbalanced(tl, key, tr),
|
||||||
|
(0, _) => <Self::T as Monad>::bind(self.assume_node(&tr), move |nr| {
|
||||||
|
let (trl, trr, kr) = self.split(&nr);
|
||||||
|
let (rlh, rrh) = (self.height(&trl), self.height(&trr));
|
||||||
|
if rlh > rrh {
|
||||||
|
<Self::T as Monad>::bind(self.assume_node(&trl), move |nrl| {
|
||||||
|
let (trll, trlr, krl) = self.split(&nrl);
|
||||||
|
Self::T::bind2(
|
||||||
|
self.clone().join_key_balanced_tree(tl, key, trll),
|
||||||
|
self.clone().join_key_balanced_tree(trlr, kr, trr),
|
||||||
|
|ti, to| self.join_key_balanced(ti, krl, to),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
<Self::T as Monad>::bind(
|
||||||
|
self.clone().join_key_balanced_tree(tl, key, trl),
|
||||||
|
|t| self.join_key_balanced(t, kr, trr),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
(_, 0) => <Self::T as Monad>::bind(self.assume_node(&tl), move |nl| {
|
||||||
|
let (tll, tlr, kl) = self.split(&nl);
|
||||||
|
let (llh, lrh) = (self.height(&tll), self.height(&tlr));
|
||||||
|
if llh < lrh {
|
||||||
|
<Self::T as Monad>::bind(self.assume_node(&tlr), move |nlr| {
|
||||||
|
let (tlrl, tlrr, klr) = self.split(&nlr);
|
||||||
|
Self::T::bind2(
|
||||||
|
self.clone().join_key_balanced_tree(tll, kl, tlrl),
|
||||||
|
self.clone().join_key_balanced_tree(tlrr, key, tr),
|
||||||
|
|to, ti| self.join_key_balanced(to, klr, ti),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
<Self::T as Monad>::bind(
|
||||||
|
self.clone().join_key_balanced_tree(tlr, key, tr),
|
||||||
|
|t| self.join_key_balanced(tll, kl, t),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
(_, _) => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
172
src/flow/binary/avl.rs
Normal file
172
src/flow/binary/avl.rs
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
use std::{fmt::Display, marker::PhantomData, rc::Rc};
|
||||||
|
|
||||||
|
use crate::flow::comparator::*;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
struct AvlN<A> {
|
||||||
|
l: AvlT<A>,
|
||||||
|
r: AvlT<A>,
|
||||||
|
key: Rc<A>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A> Clone for AvlN<A> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
l: self.l.clone(),
|
||||||
|
r: self.r.clone(),
|
||||||
|
key: self.key.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: Display> Display for AvlN<A> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_fmt(format_args!("({} {} {})", self.l, self.key, self.r))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AvlR<A> {
|
||||||
|
node: Rc<AvlN<A>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A> Clone for AvlR<A> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
node: self.node.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: Display> Display for AvlR<A> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_fmt(format_args!("{}", self.node))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AvlT<A> {
|
||||||
|
reference: Option<AvlR<A>>,
|
||||||
|
height: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A> Clone for AvlT<A> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
reference: self.reference.clone(),
|
||||||
|
height: self.height,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: Display> Display for AvlT<A> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match &self.reference {
|
||||||
|
Some(reference) => f.write_fmt(format_args!("{}", reference)),
|
||||||
|
None => f.write_fmt(format_args!("-")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AvlTs<A> {
|
||||||
|
_a: PhantomData<A>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A> AvlTs<A> {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self { _a: PhantomData }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A> Clone for AvlTs<A> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, A: 'a + PartialOrd> BinaryTrees<'a> for AvlTs<A> {
|
||||||
|
type Node = AvlN<A>;
|
||||||
|
|
||||||
|
type Reference = AvlR<A>;
|
||||||
|
|
||||||
|
type Tree = AvlT<A>;
|
||||||
|
|
||||||
|
type Key = A;
|
||||||
|
|
||||||
|
type Comparator = DefaultComparator;
|
||||||
|
|
||||||
|
type T = instances::solo::SoloInstance;
|
||||||
|
|
||||||
|
fn comparator(&self) -> &Self::Comparator {
|
||||||
|
&DefaultComparator
|
||||||
|
}
|
||||||
|
|
||||||
|
fn split(&self, node: &Self::Node) -> Split<'a, Self> {
|
||||||
|
(node.l.clone(), node.r.clone(), node.key.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tree_of(&self, node: Self::Node) -> BTWrap<'a, Self, Self::Tree> {
|
||||||
|
AvlT {
|
||||||
|
height: std::cmp::max(node.l.height, node.r.height)
|
||||||
|
.checked_add(1)
|
||||||
|
.unwrap(),
|
||||||
|
reference: Some(AvlR { node: node.into() }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resolve(&self, reference: &Self::Reference) -> BTWrap<'a, Self, Self::Node> {
|
||||||
|
reference.node.as_ref().clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn equal(&self, _rhs: &Self::Reference, _lhs: &Self::Reference) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn refer(&self, tree: &Self::Tree) -> Option<Self::Reference> {
|
||||||
|
tree.reference.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, A: 'a + PartialOrd> BinaryTreesMutable<'a> for AvlTs<A> {
|
||||||
|
fn empty(&self) -> Self::Tree {
|
||||||
|
AvlT {
|
||||||
|
reference: None,
|
||||||
|
height: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn join_key(
|
||||||
|
self,
|
||||||
|
tl: Self::Tree,
|
||||||
|
key: KeyRc<'a, Self>,
|
||||||
|
tr: Self::Tree,
|
||||||
|
) -> BTWrap<'a, Self, Self::Node> {
|
||||||
|
self.join_key_balanced(tl, key, tr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn split_key_empty(
|
||||||
|
&self,
|
||||||
|
_tree: Self::Tree,
|
||||||
|
_key: KeyRc<'a, Self>,
|
||||||
|
) -> BTWrap<'a, Self, KeySplit<'a, Self>> {
|
||||||
|
(self.empty(), self.empty())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, A: 'a + PartialOrd> BinaryTreesAvl<'a> for AvlTs<A> {
|
||||||
|
fn height(&self, tree: &Self::Tree) -> u64 {
|
||||||
|
tree.height
|
||||||
|
}
|
||||||
|
|
||||||
|
fn leaf_height_error<T: 'a>(&self, height: u64) -> BTWrap<'a, Self, T> {
|
||||||
|
panic!("leaf height error: {height}.")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn join_key_unbalanced(
|
||||||
|
&self,
|
||||||
|
tl: Self::Tree,
|
||||||
|
key: KeyRc<'a, Self>,
|
||||||
|
tr: Self::Tree,
|
||||||
|
) -> BTWrap<'a, Self, Self::Node> {
|
||||||
|
AvlN { l: tl, r: tr, key }
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,7 @@ pub enum Comparison {
|
|||||||
/// Returns [`Comparison`] saying which value is smaller.
|
/// Returns [`Comparison`] saying which value is smaller.
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use radn_rs::flow::traversible::*;
|
/// # use radn_rs::flow::comparator::*;
|
||||||
/// assert_eq!(DefaultComparator.pick_smaller(&1, &3), Comparison::L);
|
/// assert_eq!(DefaultComparator.pick_smaller(&1, &3), Comparison::L);
|
||||||
/// assert_eq!(DefaultComparator.pick_smaller(&2, &2), Comparison::E);
|
/// assert_eq!(DefaultComparator.pick_smaller(&2, &2), Comparison::E);
|
||||||
/// assert_eq!(DefaultComparator.pick_smaller(&3, &1), Comparison::R);
|
/// assert_eq!(DefaultComparator.pick_smaller(&3, &1), Comparison::R);
|
||||||
|
@ -148,6 +148,14 @@ pub trait MonadExt<'a>: Monad<'a> {
|
|||||||
) -> Self::F<B> {
|
) -> Self::F<B> {
|
||||||
Self::iterate(BindableMut::new(a, f))
|
Self::iterate(BindableMut::new(a, f))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bind2<A: 'a, B: 'a, C: 'a>(
|
||||||
|
fa: Self::F<A>,
|
||||||
|
fb: Self::F<B>,
|
||||||
|
f: impl 'a + FnOnce(A, B) -> Self::F<C>,
|
||||||
|
) -> Self::F<C> {
|
||||||
|
Self::join(Self::la2(f, fa, fb))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Monad<'a>> MonadExt<'a> for T {}
|
impl<'a, T: Monad<'a>> MonadExt<'a> for T {}
|
||||||
|
20
src/rstd.rs
20
src/rstd.rs
@ -36,23 +36,3 @@ impl<S: Serializable> ExtSerializable for S {
|
|||||||
vec
|
vec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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<'a>: Context<'a> {
|
|
||||||
/// Convert a fallible wrapped into a wrapped result.
|
|
||||||
fn unstuff<A: 'a, E: 'a>(
|
|
||||||
wa: WrapE<'a, A, E, Self::Fallible>,
|
|
||||||
) -> Wrap<'a, Result<A, E>, Self::T> {
|
|
||||||
Self::Fallible::unstuff(wa)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert a wrapped result into a fallible wrapped.
|
|
||||||
fn stuff<A: 'a, E: 'a>(fa: Wrap<'a, Result<A, E>, Self::T>) -> WrapE<'a, A, E, Self::Fallible> {
|
|
||||||
Self::Fallible::stuff(fa)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, Ctx: Context<'a>> FallibleContext<'a> for Ctx {}
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::{flow::comparator::*, func::*};
|
use crate::flow::comparator::*;
|
||||||
|
use crate::func::*;
|
||||||
|
|
||||||
use super::{binary::*, *};
|
use super::{binary::*, *};
|
||||||
|
|
||||||
@ -146,6 +147,13 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundNode<'a, Ctx, A> {
|
|||||||
Ok(BoundTree { tree, bounds })
|
Ok(BoundTree { tree, bounds })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn into_tree_resolution(self) -> BrTree<'a, Ctx, A> {
|
||||||
|
match self.into_tree() {
|
||||||
|
Ok(tree) => <Ctx::T as Pure>::pure(Ok(tree)),
|
||||||
|
Err(e) => <Ctx::T as Pure>::pure(Err(ResolutionError::Parse(e))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
l: BoundTree<'a, Ctx, A>,
|
l: BoundTree<'a, Ctx, A>,
|
||||||
r: BoundTree<'a, Ctx, A>,
|
r: BoundTree<'a, Ctx, A>,
|
||||||
@ -161,7 +169,13 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundNode<'a, Ctx, A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type BoundKeySplit<'a, Ctx, A> = (BoundTree<'a, Ctx, A>, BoundTree<'a, Ctx, A>);
|
||||||
|
|
||||||
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundTree<'a, Ctx, A> {
|
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundTree<'a, Ctx, A> {
|
||||||
|
pub fn height(&self) -> u64 {
|
||||||
|
self.tree.height
|
||||||
|
}
|
||||||
|
|
||||||
pub fn empty(factory: Fctr<'a, Ctx, A>) -> Self {
|
pub fn empty(factory: Fctr<'a, Ctx, A>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
tree: AvlTree::empty(factory),
|
tree: AvlTree::empty(factory),
|
||||||
@ -169,11 +183,44 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundTree<'a, Ctx, A> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn empty_bound(factory: Fctr<'a, Ctx, A>, bounds: Bounds<A>) -> Self {
|
||||||
|
Self {
|
||||||
|
tree: AvlTree::empty(factory),
|
||||||
|
bounds,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn reference(&self) -> Option<BoundReference<'a, Ctx, A>> {
|
pub fn reference(&self) -> Option<BoundReference<'a, Ctx, A>> {
|
||||||
let reference = self.tree.reference()?;
|
let reference = self.tree.reference()?;
|
||||||
let bounds = self.bounds.clone();
|
let bounds = self.bounds.clone();
|
||||||
Some(BoundReference { reference, bounds })
|
Some(BoundReference { reference, bounds })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn split_empty(
|
||||||
|
bounds: Bounds<A>,
|
||||||
|
key: &Rc<A>,
|
||||||
|
factory: &Fctr<'a, Ctx, A>,
|
||||||
|
comparator: &impl Comparator<A>,
|
||||||
|
) -> Result<(Self, Self), BoundsError<A>> {
|
||||||
|
let (bl, br) = bounds.split(key, comparator)?;
|
||||||
|
Ok((
|
||||||
|
Self::empty_bound(factory.clone(), bl),
|
||||||
|
Self::empty_bound(factory.clone(), br),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn split_empty_res(
|
||||||
|
self,
|
||||||
|
key: Rc<A>,
|
||||||
|
factory: Fctr<'a, Ctx, A>,
|
||||||
|
comparator: Rc<impl 'a + Comparator<A>>,
|
||||||
|
) -> BrKeySplit<'a, Ctx, A> {
|
||||||
|
<Ctx::T as Pure>::pure(
|
||||||
|
Self::split_empty(self.bounds, &key, &factory, comparator.as_ref())
|
||||||
|
.map_err(BoundError::Bounds)
|
||||||
|
.map_err(ResolutionError::Parse),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Clone for BoundTree<'a, Ctx, A> {
|
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Clone for BoundTree<'a, Ctx, A> {
|
||||||
@ -188,13 +235,18 @@ impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> Clone for BoundTree<'a, Ctx,
|
|||||||
pub type BoundResolutionError<'a, Ctx, A> =
|
pub type BoundResolutionError<'a, Ctx, A> =
|
||||||
ResolutionError<<Ctx as Context<'a>>::LookupError, BoundErrorA<'a, Ctx, A>>;
|
ResolutionError<<Ctx as Context<'a>>::LookupError, BoundErrorA<'a, Ctx, A>>;
|
||||||
|
|
||||||
pub type BoundResolutionResult<'a, Ctx, A> =
|
pub type BoundResolutionResult<'a, Ctx, A, T> = Result<T, BoundResolutionError<'a, Ctx, A>>;
|
||||||
Result<BoundNode<'a, Ctx, A>, BoundResolutionError<'a, Ctx, A>>;
|
|
||||||
|
|
||||||
pub type BoundResolution<'a, Ctx, A> = Wrapped<'a, Ctx, BoundResolutionResult<'a, Ctx, A>>;
|
pub type BoundResolution<'a, Ctx, A, T> = Wrapped<'a, Ctx, BoundResolutionResult<'a, Ctx, A, T>>;
|
||||||
|
|
||||||
|
pub type BrNode<'a, Ctx, A> = BoundResolution<'a, Ctx, A, BoundNode<'a, Ctx, A>>;
|
||||||
|
|
||||||
|
pub type BrTree<'a, Ctx, A> = BoundResolution<'a, Ctx, A, BoundTree<'a, Ctx, A>>;
|
||||||
|
|
||||||
|
pub type BrKeySplit<'a, Ctx, A> = BoundResolution<'a, Ctx, A, BoundKeySplit<'a, Ctx, A>>;
|
||||||
|
|
||||||
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundReference<'a, Ctx, A> {
|
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>> BoundReference<'a, Ctx, A> {
|
||||||
pub fn resolve(&self, comparator: Rc<impl 'a + Comparator<A>>) -> BoundResolution<'a, Ctx, A> {
|
pub fn resolve(&self, comparator: Rc<impl 'a + Comparator<A>>) -> BrNode<'a, Ctx, A> {
|
||||||
let bounds = self.bounds.clone();
|
let bounds = self.bounds.clone();
|
||||||
<Ctx::T as Functor>::fmap(
|
<Ctx::T as Functor>::fmap(
|
||||||
move |resolution| {
|
move |resolution| {
|
||||||
|
111
src/rstd/collections/avl/context.rs
Normal file
111
src/rstd/collections/avl/context.rs
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
use crate::flow::{binary::*, comparator::*};
|
||||||
|
use crate::func::*;
|
||||||
|
use crate::rstd::fallible::*;
|
||||||
|
|
||||||
|
use super::{bounds::*, *};
|
||||||
|
|
||||||
|
pub struct BoundContext<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, C: 'a + Comparator<A>> {
|
||||||
|
factory: A::Fctr,
|
||||||
|
comparator: Rc<C>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, C: 'a + Comparator<A>> Clone
|
||||||
|
for BoundContext<'a, Ctx, A, C>
|
||||||
|
{
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
factory: self.factory.clone(),
|
||||||
|
comparator: self.comparator.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, C: 'a + Comparator<A>> BinaryTrees<'a>
|
||||||
|
for BoundContext<'a, Ctx, A, C>
|
||||||
|
{
|
||||||
|
type Node = BoundNode<'a, Ctx, A>;
|
||||||
|
type Reference = BoundReference<'a, Ctx, A>;
|
||||||
|
type Tree = BoundTree<'a, Ctx, A>;
|
||||||
|
type Key = A;
|
||||||
|
type Comparator = C;
|
||||||
|
|
||||||
|
type T = FallibleMonad<'a, Ctx, BoundResolutionError<'a, Ctx, A>>;
|
||||||
|
|
||||||
|
fn comparator(&self) -> &Self::Comparator {
|
||||||
|
&self.comparator
|
||||||
|
}
|
||||||
|
|
||||||
|
fn split(&self, node: &Self::Node) -> Split<'a, Self> {
|
||||||
|
node.split()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tree_of(&self, node: Self::Node) -> BTWrap<'a, Self, Self::Tree> {
|
||||||
|
match node.into_tree() {
|
||||||
|
Ok(tree) => <Self::T as Pure>::pure(tree),
|
||||||
|
Err(e) => <Self::T as Fail<_>>::fail(ResolutionError::Parse(e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resolve(&self, reference: &Self::Reference) -> BTWrap<'a, Self, Self::Node> {
|
||||||
|
Ctx::stuff(reference.resolve(self.comparator.clone()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn equal(&self, rhs: &Self::Reference, lhs: &Self::Reference) -> bool {
|
||||||
|
BoundReference::equal(lhs, rhs, self.comparator.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn refer(&self, tree: &Self::Tree) -> Option<Self::Reference> {
|
||||||
|
tree.reference()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, C: 'a + Comparator<A>> BinaryTreesMutable<'a>
|
||||||
|
for BoundContext<'a, Ctx, A, C>
|
||||||
|
{
|
||||||
|
fn empty(&self) -> Self::Tree {
|
||||||
|
BoundTree::empty(self.factory.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn join_key(
|
||||||
|
self,
|
||||||
|
tl: Self::Tree,
|
||||||
|
key: KeyRc<'a, Self>,
|
||||||
|
tr: Self::Tree,
|
||||||
|
) -> BTWrap<'a, Self, Self::Node> {
|
||||||
|
self.join_key_balanced(tl, key, tr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn split_key_empty(
|
||||||
|
&self,
|
||||||
|
tree: Self::Tree,
|
||||||
|
key: KeyRc<'a, Self>,
|
||||||
|
) -> BTWrap<'a, Self, KeySplit<'a, Self>> {
|
||||||
|
Ctx::stuff(tree.split_empty_res(key, self.factory.clone(), self.comparator.clone()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Ctx: Context<'a>, A: Mentionable<'a, Ctx>, C: 'a + Comparator<A>> BinaryTreesAvl<'a>
|
||||||
|
for BoundContext<'a, Ctx, A, C>
|
||||||
|
{
|
||||||
|
fn height(&self, tree: &Self::Tree) -> u64 {
|
||||||
|
tree.height()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn leaf_height_error<T: 'a>(&self, height: u64) -> BTWrap<'a, Self, T> {
|
||||||
|
<FallibleMonad<'a, Ctx, _> as Fail<_>>::fail(ResolutionError::Parse(BoundError::Avl(
|
||||||
|
AvlError::LeafHeight(height),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn join_key_unbalanced(
|
||||||
|
&self,
|
||||||
|
tl: Self::Tree,
|
||||||
|
key: KeyRc<'a, Self>,
|
||||||
|
tr: Self::Tree,
|
||||||
|
) -> BTWrap<'a, Self, Self::Node> {
|
||||||
|
match BoundNode::new(tl, tr, key, self.comparator.as_ref()) {
|
||||||
|
Ok(n) => <FallibleMonad<'a, Ctx, _> as Pure>::pure(n),
|
||||||
|
Err(e) => <FallibleMonad<'a, Ctx, _> as Fail<_>>::fail(ResolutionError::Parse(e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
use crate::flow::traversible::*;
|
use crate::flow::traversible::*;
|
||||||
use crate::func::*;
|
use crate::func::*;
|
||||||
use crate::rstd::{fallible::*, *};
|
use crate::rstd::fallible::*;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
@ -7,3 +7,23 @@ pub type FallibleMonad<'a, Ctx, E> = <<Ctx as Context<'a>>::Fallible as MonadFai
|
|||||||
|
|
||||||
/// Preferred [Wrapped] [Result].
|
/// Preferred [Wrapped] [Result].
|
||||||
pub type FallibleWrapped<'a, Ctx, A, E> = Wrap<'a, A, FallibleMonad<'a, Ctx, E>>;
|
pub type FallibleWrapped<'a, Ctx, A, E> = Wrap<'a, A, FallibleMonad<'a, Ctx, E>>;
|
||||||
|
|
||||||
|
/// 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<'a>: Context<'a> {
|
||||||
|
/// Convert a fallible wrapped into a wrapped result.
|
||||||
|
fn unstuff<A: 'a, E: 'a>(
|
||||||
|
wa: WrapE<'a, A, E, Self::Fallible>,
|
||||||
|
) -> Wrap<'a, Result<A, E>, Self::T> {
|
||||||
|
Self::Fallible::unstuff(wa)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a wrapped result into a fallible wrapped.
|
||||||
|
fn stuff<A: 'a, E: 'a>(fa: Wrap<'a, Result<A, E>, Self::T>) -> WrapE<'a, A, E, Self::Fallible> {
|
||||||
|
Self::Fallible::stuff(fa)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Ctx: Context<'a>> FallibleContext<'a> for Ctx {}
|
||||||
|
Loading…
Reference in New Issue
Block a user