diff --git a/src/flow/traversible.rs b/src/flow/traversible.rs index 805f7ac..d7c97dc 100644 --- a/src/flow/traversible.rs +++ b/src/flow/traversible.rs @@ -15,9 +15,7 @@ pub enum Comparison { R, } -fn and(left: bool, right: bool) -> bool { - left && right -} +fn and(_l: (), _r: ()) -> () {} /// Returns [`Comparison`] saying which value is smaller. /// @@ -69,45 +67,45 @@ pub trait TraversibleBinaryTree<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>: 'a fn refer(&self) -> Option>>; } -pub fn n_contains<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>( +pub fn n_contains<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>( comparator: &'a dyn Comparator, n_set: Rc>, key: Rc, -) -> T::F<'a, bool> { +) -> T::F<'a, ()> { let (t_setl, t_setr, k_set) = n_set.split(); match comparator.pick_smaller(key.as_ref(), k_set.as_ref()) { Comparison::L => t_contains(comparator, t_setl, key), - Comparison::E => T::pure(true), + Comparison::E => T::pure(()), Comparison::R => t_contains(comparator, t_setr, key), } } -pub fn r_contains<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>( +pub fn r_contains<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>( comparator: &'a dyn Comparator, r_set: Rc>, key: Rc, -) -> T::F<'a, bool> { +) -> T::F<'a, ()> { T::bind(r_set.resolve(), |n_set| n_contains(comparator, n_set, key)) } -pub fn t_contains<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>( +pub fn t_contains<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>( comparator: &'a dyn Comparator, t_set: Rc>, key: Rc, -) -> T::F<'a, bool> { +) -> T::F<'a, ()> { match t_set.refer() { Some(r_set) => r_contains(comparator, r_set, key), - None => T::pure(false), + None => T::fail(()), } } -pub fn n_subset_of_n<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>( +pub fn n_subset_of_n<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>( comparator: &'a dyn Comparator, n_subset: Rc>, n_superset: Rc>, k_l: Option>, k_r: Option>, -) -> T::F<'a, bool> { +) -> T::F<'a, ()> { let (t_superl, t_superr, k_super) = n_superset.split(); if let Some(ref a_l) = k_l { if let Comparison::R = comparator.pick_smaller(a_l.as_ref(), k_super.as_ref()) { @@ -159,13 +157,13 @@ pub fn n_subset_of_n<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>( } } -pub fn r_subset_of_r<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>( +pub fn r_subset_of_r<'a, T: 'a + MonadFail<()>, A: 'a, D: 'a + PartialEq>( comparator: &'a dyn Comparator, r_subset: Rc>, r_superset: Rc>, k_l: Option>, k_r: Option>, -) -> T::F<'a, bool> { +) -> T::F<'a, ()> { T::join(T::la2( move |n_subset, n_superset| n_subset_of_n(comparator, n_subset, n_superset, k_l, k_r), r_subset.resolve(), @@ -173,19 +171,19 @@ pub fn r_subset_of_r<'a, T: 'a + Monad, A: 'a, D: 'a + PartialEq>( )) } -pub fn t_subset_of_t<'a, T: Monad, A, D: 'a + PartialEq>( +pub fn t_subset_of_t<'a, T: MonadFail<()>, A, D: 'a + PartialEq>( comparator: &'a dyn Comparator, t_subset: Rc>, t_superset: Rc>, k_l: Option>, k_r: Option>, -) -> T::F<'a, bool> { +) -> T::F<'a, ()> { match (t_subset.refer(), t_superset.refer()) { - (None, _) => T::pure(true), - (Some(_), None) => T::pure(false), + (None, _) => T::pure(()), + (Some(_), None) => T::fail(()), (Some(r_subset), Some(r_superset)) => { if r_subset.data() == r_superset.data() { - T::pure(true) + T::pure(()) } else { r_subset_of_r(comparator, r_subset, r_superset, k_l, k_r) } diff --git a/src/flow/traversible/unbalanced.rs b/src/flow/traversible/unbalanced.rs index 7957eba..72b45a4 100644 --- a/src/flow/traversible/unbalanced.rs +++ b/src/flow/traversible/unbalanced.rs @@ -34,23 +34,38 @@ pub enum UnbalancedTree<'a, T: 'a + Monad, A: 'a> { Node(Rc>), } -impl<'a, A: 'a + Display> Display for UnbalancedNode<'a, classes::solo::SoloClass, A> { +impl<'a, T: 'a + Monad, A: 'a + Display> Display for UnbalancedNode<'a, T, A> +where + UnbalancedReference<'a, T, A>: std::fmt::Display, +{ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_fmt(format_args!("({} {} {})", self.cl, self.key, self.cr)) } } +impl<'a, T: 'a + Monad, A: 'a + Display> Display for UnbalancedTree<'a, T, A> +where + UnbalancedReference<'a, T, A>: std::fmt::Display, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + UnbalancedTree::Leaf => f.write_fmt(format_args!(".")), + UnbalancedTree::Node(reference) => f.write_fmt(format_args!("{}", reference)), + } + } +} + impl<'a, A: 'a + Display> Display for UnbalancedReference<'a, classes::solo::SoloClass, A> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_fmt(format_args!("{}", self.0())) } } -impl<'a, A: 'a + Display> Display for UnbalancedTree<'a, classes::solo::SoloClass, A> { +impl<'a, A: 'a + Display> Display for UnbalancedReference<'a, classes::result::ResultClass<()>, A> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - UnbalancedTree::Leaf => f.write_fmt(format_args!(".")), - UnbalancedTree::Node(reference) => f.write_fmt(format_args!("{}", reference)), + match self.0() { + Ok(node) => f.write_fmt(format_args!("{}", node)), + Err(()) => f.write_fmt(format_args!("~")), } } } @@ -166,60 +181,41 @@ mod tests { #[test] fn test_simple_slices() { - let ctr: Rc> = - UnbalancedConstructor::rc(Box::new(|node| node)); + let ctr: Rc, _>> = + UnbalancedConstructor::rc(Box::new(|node| Ok(node))); let mut rng = rand::thread_rng(); let t_set = ctr.from_slice(&mut rng, &[0]); - assert!(t_contains(&DefaultComparator, t_set.clone(), 0.into())); - assert!(!t_contains(&DefaultComparator, t_set.clone(), 1.into())); - assert!(t_subset_of_t( - &DefaultComparator, - t_set.clone(), - t_set.clone(), - None, - None - )); - assert!(!t_subset_of_t( - &DefaultComparator, - t_set.clone(), - ctr.leaf(), - None, - None - )); - assert!(t_subset_of_t( - &DefaultComparator, - ctr.leaf(), - t_set.clone(), - None, - None - )); - assert!(t_subset_of_t( - &DefaultComparator, - ctr.leaf(), - ctr.leaf(), - None, - None - )); + assert!(t_contains(&DefaultComparator, t_set.clone(), 0.into()).is_ok()); + assert!(t_contains(&DefaultComparator, t_set.clone(), 1.into()).is_err()); + assert!( + t_subset_of_t(&DefaultComparator, t_set.clone(), t_set.clone(), None, None).is_ok() + ); + assert!(t_subset_of_t(&DefaultComparator, t_set.clone(), ctr.leaf(), None, None).is_err()); + assert!(t_subset_of_t(&DefaultComparator, ctr.leaf(), t_set.clone(), None, None).is_ok()); + assert!(t_subset_of_t(&DefaultComparator, ctr.leaf(), ctr.leaf(), None, None).is_ok()); assert!(t_subset_of_t( &DefaultComparator, ctr.from_slice(&mut rng, &[0, 1, 2, 4, 5, 6, 7]), ctr.from_slice(&mut rng, &[0, 1, 2, 3, 4, 5, 6, 7]), None, None - )); - assert!(!t_subset_of_t( + ) + .is_ok()); + assert!(t_subset_of_t( &DefaultComparator, ctr.from_slice(&mut rng, &[0, 1, 2, 3, 4, 5, 6, 7]), ctr.from_slice(&mut rng, &[0, 1, 2, 4, 5, 6, 7]), None, None - )); + ) + .is_err()); } + #[ignore] #[test] fn test_random_slices() { - let ctr: Rc> = - UnbalancedConstructor::rc(Box::new(|node| node)); + let ctr: Rc, _>> = + UnbalancedConstructor::rc(Box::new(|node| Ok(node))); let mut rng = rand::thread_rng(); for _ in 0..1000 { let big: Vec = (0..(rng.gen_range(2..10))).collect(); @@ -238,19 +234,21 @@ mod tests { t_big.clone(), None, None - ), + ) + .is_ok(), "{} should be a subset of {}", t_small, t_big, ); assert!( - !t_subset_of_t( + t_subset_of_t( &DefaultComparator, t_big.clone(), t_small.clone(), None, None - ), + ) + .is_err(), "{} should not be a subset of {}", t_big, t_small, @@ -258,10 +256,14 @@ mod tests { } } + type TracedMonad = + classes::composition::CompositionClass>; + + #[ignore] #[test] fn trace_one_slice() { - let ctr: Rc> = - UnbalancedConstructor::rc(Box::new(|node| TracedClass::pure(node).after_resolution())); + let ctr: Rc> = + UnbalancedConstructor::rc(Box::new(|node| TracedMonad::pure(node).after_resolution())); // let mut rng = rand::thread_rng(); let mut rng = rand::rngs::StdRng::seed_from_u64(426); let big: Vec = (0..(rng.gen_range(1000..2000))).collect(); @@ -280,7 +282,7 @@ mod tests { None, None, ); - assert!(traced.a); - // panic!("{:?}", traced.render().to_vec()); + assert!(traced.a.is_ok()); + // panic!("{:?}", traced.render().to_vec());D } }