computation-types 0.0.0

Types for abstract mathematical computation
Documentation
use core::fmt;

use crate::{
    impl_core_ops, peano::One, Computation, ComputationFn, Function, Name, NamedArgs, Names,
};

#[derive(Clone, Copy, Debug)]
pub struct Enumerate<A, F>
where
    Self: Computation,
{
    pub child: A,
    pub f: Function<(Name, Name), F>,
}

impl<A, F> Computation for Enumerate<A, F>
where
    A: Computation<Dim = One>,
    F: Computation,
{
    type Dim = F::Dim;
    type Item = F::Item;
}

impl<A, F> ComputationFn for Enumerate<A, F>
where
    Self: Computation,
    A: ComputationFn,
    Enumerate<A::Filled, F>: Computation,
{
    type Filled = Enumerate<A::Filled, F>;

    fn fill(self, named_args: NamedArgs) -> Self::Filled {
        Enumerate {
            child: self.child.fill(named_args),
            f: self.f,
        }
    }

    fn arg_names(&self) -> Names {
        self.child.arg_names()
    }
}

impl_core_ops!(Enumerate<A, F>);

impl<A, F> fmt::Display for Enumerate<A, F>
where
    Self: Computation,
    A: fmt::Display,
    F: fmt::Display,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}.enumerate({})", self.child, self.f.body)
    }
}

#[cfg(test)]
mod tests {
    use proptest::prelude::*;
    use test_strategy::proptest;

    use crate::{arg1, val1, Computation, Function};

    #[proptest]
    fn enumerate_should_display(xs: Vec<usize>) {
        let inp = val1!(xs.iter().cloned());
        let f = Function::anonymous(("x", "i"), arg1!("x", usize) + arg1!("i", usize));
        prop_assert_eq!(
            inp.clone().enumerate(f).to_string(),
            format!("{}.enumerate({})", inp, f.body)
        );
    }
}