Struct Xpr

Source
pub struct Xpr<T>(/* private fields */);
Expand description

An expression. Xpr together with the Fold trait are at the heart of this crate.

The nested type is a specific struct representing the operation, e.g. ops::Add.

Xpr instances should be instantiated via the Xpr::new method, which creates Xpr<ops::Term> leaf expressions. The other variants are constructed from them by applying operations to the leaf expressions.

use xpr::*;
let x = Xpr::new(5);
let y = Xpr::new(1);
let z = x * y;
//type of z is xpr::Xpr<xpr::ops::Mul<xpr::Xpr<xpr::ops::Term<{integer}>>, xpr::Xpr<xpr::ops::Term<{integer}>>>>

Implementations§

Source§

impl<T> Xpr<Term<T>>

Source

pub const fn new(t: T) -> Self

creates a new leaf expression.

Examples found in repository?
examples/fortitwoify.rs (line 12)
11    fn fold(&mut self, _: &Term<i32>) -> Self::Output {
12        Xpr::new(42)
13    }
14}
15
16fn main() {
17    // create a new expression representing a chained addition
18    let x = Xpr::new(10) + Xpr::new(15) + Xpr::new(17);
19    println!("x = {:?}", x);
20
21    println!("x evaluates to {}.", x.eval());
22    assert_eq!(x.eval(), 42);
23
24    // let's use the Fortytwoify folder
25    println!("\n>>> Fortitwoify x <<<\n");
26    let x = Fortytwoify.fold(&x);
27    println!("x = {:?}", x);
28
29    println!("x evaluates to {}.", x.eval());
30    assert_eq!(x.eval(), 126);
31}
More examples
Hide additional examples
examples/substitution.rs (line 13)
12    fn fold(&mut self, &Term(x): &Term<i32>) -> Self::Output {
13        Xpr::new(x - 42) + Xpr::new(42)
14    }
15}
16
17fn main() {
18    // create a new expression representing a chained addition
19    let x = Xpr::new(10) + Xpr::new(15) + Xpr::new(17);
20    println!("x = {:?}", x);
21
22    println!("x evaluates to {}.", x.eval());
23    assert_eq!(x.eval(), 42);
24
25    // let's use the Substitution folder
26    println!("Substitution fold...");
27    let x = Substitution.fold(&x);
28    println!("x = {:?}", x);
29
30    println!("x evaluates to {}.", x.eval());
31    assert_eq!(x.eval(), 42);
32}
examples/evaluator.rs (line 17)
15fn main() {
16    // create a new expression representing a chained addition
17    let x = Xpr::new(10) + Xpr::new(15) + Xpr::new(17);
18    println!("x = {:?}", x);
19
20    // use the Evaluator to evaluate the expression
21    let res = Evaluator.fold(&x);
22
23    println!("x evaluates to {}.", res);
24    assert_eq!(res, 42);
25
26    // note that `Xpr::eval` is syntactic sugar around a similar generic
27    // Evaluator struct
28    assert_eq!(res, x.eval());
29}
Source§

impl<U> Xpr<U>

Source

pub fn eval<T>(&self) -> <Self as Foldable<Evaluator<T>>>::Output
where T: Clone, U: Foldable<Evaluator<T>>, Evaluator<T>: Fold<U> + Fold<Self>,

evaluates the expression by unwrapping all terminals and applying the operations in the expression. It is synactic sugar for folding the expression with [Evaluator].

Examples found in repository?
examples/evaluator.rs (line 28)
15fn main() {
16    // create a new expression representing a chained addition
17    let x = Xpr::new(10) + Xpr::new(15) + Xpr::new(17);
18    println!("x = {:?}", x);
19
20    // use the Evaluator to evaluate the expression
21    let res = Evaluator.fold(&x);
22
23    println!("x evaluates to {}.", res);
24    assert_eq!(res, 42);
25
26    // note that `Xpr::eval` is syntactic sugar around a similar generic
27    // Evaluator struct
28    assert_eq!(res, x.eval());
29}
More examples
Hide additional examples
examples/substitution.rs (line 22)
17fn main() {
18    // create a new expression representing a chained addition
19    let x = Xpr::new(10) + Xpr::new(15) + Xpr::new(17);
20    println!("x = {:?}", x);
21
22    println!("x evaluates to {}.", x.eval());
23    assert_eq!(x.eval(), 42);
24
25    // let's use the Substitution folder
26    println!("Substitution fold...");
27    let x = Substitution.fold(&x);
28    println!("x = {:?}", x);
29
30    println!("x evaluates to {}.", x.eval());
31    assert_eq!(x.eval(), 42);
32}
examples/fortitwoify.rs (line 21)
16fn main() {
17    // create a new expression representing a chained addition
18    let x = Xpr::new(10) + Xpr::new(15) + Xpr::new(17);
19    println!("x = {:?}", x);
20
21    println!("x evaluates to {}.", x.eval());
22    assert_eq!(x.eval(), 42);
23
24    // let's use the Fortytwoify folder
25    println!("\n>>> Fortitwoify x <<<\n");
26    let x = Fortytwoify.fold(&x);
27    println!("x = {:?}", x);
28
29    println!("x evaluates to {}.", x.eval());
30    assert_eq!(x.eval(), 126);
31}

Trait Implementations§

Source§

impl<'a, L, R> Add<&'a R> for Xpr<L>
where R: Expression,

Source§

type Output = Xpr<Add<Xpr<L>, Xpr<Term<&'a R>>>>

The resulting type after applying the + operator.
Source§

fn add(self, other: &'a R) -> Self::Output

Performs the + operation. Read more
Source§

impl<L, R> Add<Xpr<R>> for Xpr<L>

Source§

type Output = Xpr<Add<Xpr<L>, Xpr<R>>>

The resulting type after applying the + operator.
Source§

fn add(self, other: Xpr<R>) -> Self::Output

Performs the + operation. Read more
Source§

impl<'a, L, R> BitAnd<&'a R> for Xpr<L>
where R: Expression,

Source§

type Output = Xpr<BitAnd<Xpr<L>, Xpr<Term<&'a R>>>>

The resulting type after applying the & operator.
Source§

fn bitand(self, other: &'a R) -> Self::Output

Performs the & operation. Read more
Source§

impl<L, R> BitAnd<Xpr<R>> for Xpr<L>

Source§

type Output = Xpr<BitAnd<Xpr<L>, Xpr<R>>>

The resulting type after applying the & operator.
Source§

fn bitand(self, other: Xpr<R>) -> Self::Output

Performs the & operation. Read more
Source§

impl<'a, L, R> BitOr<&'a R> for Xpr<L>
where R: Expression,

Source§

type Output = Xpr<BitOr<Xpr<L>, Xpr<Term<&'a R>>>>

The resulting type after applying the | operator.
Source§

fn bitor(self, other: &'a R) -> Self::Output

Performs the | operation. Read more
Source§

impl<L, R> BitOr<Xpr<R>> for Xpr<L>

Source§

type Output = Xpr<BitOr<Xpr<L>, Xpr<R>>>

The resulting type after applying the | operator.
Source§

fn bitor(self, other: Xpr<R>) -> Self::Output

Performs the | operation. Read more
Source§

impl<'a, L, R> BitXor<&'a R> for Xpr<L>
where R: Expression,

Source§

type Output = Xpr<BitXor<Xpr<L>, Xpr<Term<&'a R>>>>

The resulting type after applying the ^ operator.
Source§

fn bitxor(self, other: &'a R) -> Self::Output

Performs the ^ operation. Read more
Source§

impl<L, R> BitXor<Xpr<R>> for Xpr<L>

Source§

type Output = Xpr<BitXor<Xpr<L>, Xpr<R>>>

The resulting type after applying the ^ operator.
Source§

fn bitxor(self, other: Xpr<R>) -> Self::Output

Performs the ^ operation. Read more
Source§

impl<T: Clone> Clone for Xpr<T>

Source§

fn clone(&self) -> Xpr<T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug> Debug for Xpr<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a, L, R> Div<&'a R> for Xpr<L>
where R: Expression,

Source§

type Output = Xpr<Div<Xpr<L>, Xpr<Term<&'a R>>>>

The resulting type after applying the / operator.
Source§

fn div(self, other: &'a R) -> Self::Output

Performs the / operation. Read more
Source§

impl<L, R> Div<Xpr<R>> for Xpr<L>

Source§

type Output = Xpr<Div<Xpr<L>, Xpr<R>>>

The resulting type after applying the / operator.
Source§

fn div(self, other: Xpr<R>) -> Self::Output

Performs the / operation. Read more
Source§

impl<'a, L, R> Mul<&'a R> for Xpr<L>
where R: Expression,

Source§

type Output = Xpr<Mul<Xpr<L>, Xpr<Term<&'a R>>>>

The resulting type after applying the * operator.
Source§

fn mul(self, other: &'a R) -> Self::Output

Performs the * operation. Read more
Source§

impl<L, R> Mul<Xpr<R>> for Xpr<L>

Source§

type Output = Xpr<Mul<Xpr<L>, Xpr<R>>>

The resulting type after applying the * operator.
Source§

fn mul(self, other: Xpr<R>) -> Self::Output

Performs the * operation. Read more
Source§

impl<T> Neg for Xpr<T>

Source§

type Output = Xpr<Neg<Xpr<T>>>

The resulting type after applying the - operator.
Source§

fn neg(self) -> Self::Output

Performs the unary - operation. Read more
Source§

impl<T> Not for Xpr<T>

Source§

type Output = Xpr<Not<Xpr<T>>>

The resulting type after applying the ! operator.
Source§

fn not(self) -> Self::Output

Performs the unary ! operation. Read more
Source§

impl<'a, L, R> Rem<&'a R> for Xpr<L>
where R: Expression,

Source§

type Output = Xpr<Rem<Xpr<L>, Xpr<Term<&'a R>>>>

The resulting type after applying the % operator.
Source§

fn rem(self, other: &'a R) -> Self::Output

Performs the % operation. Read more
Source§

impl<L, R> Rem<Xpr<R>> for Xpr<L>

Source§

type Output = Xpr<Rem<Xpr<L>, Xpr<R>>>

The resulting type after applying the % operator.
Source§

fn rem(self, other: Xpr<R>) -> Self::Output

Performs the % operation. Read more
Source§

impl<'a, L, R> Shl<&'a R> for Xpr<L>
where R: Expression,

Source§

type Output = Xpr<Shl<Xpr<L>, Xpr<Term<&'a R>>>>

The resulting type after applying the << operator.
Source§

fn shl(self, other: &'a R) -> Self::Output

Performs the << operation. Read more
Source§

impl<L, R> Shl<Xpr<R>> for Xpr<L>

Source§

type Output = Xpr<Shl<Xpr<L>, Xpr<R>>>

The resulting type after applying the << operator.
Source§

fn shl(self, other: Xpr<R>) -> Self::Output

Performs the << operation. Read more
Source§

impl<'a, L, R> Shr<&'a R> for Xpr<L>
where R: Expression,

Source§

type Output = Xpr<Shr<Xpr<L>, Xpr<Term<&'a R>>>>

The resulting type after applying the >> operator.
Source§

fn shr(self, other: &'a R) -> Self::Output

Performs the >> operation. Read more
Source§

impl<L, R> Shr<Xpr<R>> for Xpr<L>

Source§

type Output = Xpr<Shr<Xpr<L>, Xpr<R>>>

The resulting type after applying the >> operator.
Source§

fn shr(self, other: Xpr<R>) -> Self::Output

Performs the >> operation. Read more
Source§

impl<'a, L, R> Sub<&'a R> for Xpr<L>
where R: Expression,

Source§

type Output = Xpr<Sub<Xpr<L>, Xpr<Term<&'a R>>>>

The resulting type after applying the - operator.
Source§

fn sub(self, other: &'a R) -> Self::Output

Performs the - operation. Read more
Source§

impl<L, R> Sub<Xpr<R>> for Xpr<L>

Source§

type Output = Xpr<Sub<Xpr<L>, Xpr<R>>>

The resulting type after applying the - operator.
Source§

fn sub(self, other: Xpr<R>) -> Self::Output

Performs the - operation. Read more
Source§

impl<T: Copy> Copy for Xpr<T>

Auto Trait Implementations§

§

impl<T> Freeze for Xpr<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for Xpr<T>
where T: RefUnwindSafe,

§

impl<T> Send for Xpr<T>
where T: Send,

§

impl<T> Sync for Xpr<T>
where T: Sync,

§

impl<T> Unpin for Xpr<T>
where T: Unpin,

§

impl<T> UnwindSafe for Xpr<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<L, R, U> Fold<Add<L, R>> for U
where U: Fold<L> + Fold<R>, L: Foldable<U>, R: Foldable<U>, <L as Foldable<U>>::Output: Add<<R as Foldable<U>>::Output>,

Source§

type Output = <<L as Foldable<U>>::Output as Add<<R as Foldable<U>>::Output>>::Output

The output of Fold::fold, Self will replace all instances of T in an expression by values of this type.
Source§

fn fold(&mut self, _: &Add<L, R>) -> <U as Fold<Add<L, R>>>::Output

perform the replacement
Source§

impl<L, R, U> Fold<BitAnd<L, R>> for U
where U: Fold<L> + Fold<R>, L: Foldable<U>, R: Foldable<U>, <L as Foldable<U>>::Output: BitAnd<<R as Foldable<U>>::Output>,

Source§

type Output = <<L as Foldable<U>>::Output as BitAnd<<R as Foldable<U>>::Output>>::Output

The output of Fold::fold, Self will replace all instances of T in an expression by values of this type.
Source§

fn fold(&mut self, _: &BitAnd<L, R>) -> <U as Fold<BitAnd<L, R>>>::Output

perform the replacement
Source§

impl<L, R, U> Fold<BitOr<L, R>> for U
where U: Fold<L> + Fold<R>, L: Foldable<U>, R: Foldable<U>, <L as Foldable<U>>::Output: BitOr<<R as Foldable<U>>::Output>,

Source§

type Output = <<L as Foldable<U>>::Output as BitOr<<R as Foldable<U>>::Output>>::Output

The output of Fold::fold, Self will replace all instances of T in an expression by values of this type.
Source§

fn fold(&mut self, _: &BitOr<L, R>) -> <U as Fold<BitOr<L, R>>>::Output

perform the replacement
Source§

impl<L, R, U> Fold<BitXor<L, R>> for U
where U: Fold<L> + Fold<R>, L: Foldable<U>, R: Foldable<U>, <L as Foldable<U>>::Output: BitXor<<R as Foldable<U>>::Output>,

Source§

type Output = <<L as Foldable<U>>::Output as BitXor<<R as Foldable<U>>::Output>>::Output

The output of Fold::fold, Self will replace all instances of T in an expression by values of this type.
Source§

fn fold(&mut self, _: &BitXor<L, R>) -> <U as Fold<BitXor<L, R>>>::Output

perform the replacement
Source§

impl<L, R, U> Fold<Div<L, R>> for U
where U: Fold<L> + Fold<R>, L: Foldable<U>, R: Foldable<U>, <L as Foldable<U>>::Output: Div<<R as Foldable<U>>::Output>,

Source§

type Output = <<L as Foldable<U>>::Output as Div<<R as Foldable<U>>::Output>>::Output

The output of Fold::fold, Self will replace all instances of T in an expression by values of this type.
Source§

fn fold(&mut self, _: &Div<L, R>) -> <U as Fold<Div<L, R>>>::Output

perform the replacement
Source§

impl<L, R, U> Fold<Mul<L, R>> for U
where U: Fold<L> + Fold<R>, L: Foldable<U>, R: Foldable<U>, <L as Foldable<U>>::Output: Mul<<R as Foldable<U>>::Output>,

Source§

type Output = <<L as Foldable<U>>::Output as Mul<<R as Foldable<U>>::Output>>::Output

The output of Fold::fold, Self will replace all instances of T in an expression by values of this type.
Source§

fn fold(&mut self, _: &Mul<L, R>) -> <U as Fold<Mul<L, R>>>::Output

perform the replacement
Source§

impl<T, U> Fold<Neg<T>> for U
where U: Fold<T>, T: Foldable<U>, <T as Foldable<U>>::Output: Neg,

Source§

type Output = <<T as Foldable<U>>::Output as Neg>::Output

The output of Fold::fold, Self will replace all instances of T in an expression by values of this type.
Source§

fn fold(&mut self, _: &Neg<T>) -> <U as Fold<Neg<T>>>::Output

perform the replacement
Source§

impl<T, U> Fold<Not<T>> for U
where U: Fold<T>, T: Foldable<U>, <T as Foldable<U>>::Output: Not,

Source§

type Output = <<T as Foldable<U>>::Output as Not>::Output

The output of Fold::fold, Self will replace all instances of T in an expression by values of this type.
Source§

fn fold(&mut self, _: &Not<T>) -> <U as Fold<Not<T>>>::Output

perform the replacement
Source§

impl<L, R, U> Fold<Rem<L, R>> for U
where U: Fold<L> + Fold<R>, L: Foldable<U>, R: Foldable<U>, <L as Foldable<U>>::Output: Rem<<R as Foldable<U>>::Output>,

Source§

type Output = <<L as Foldable<U>>::Output as Rem<<R as Foldable<U>>::Output>>::Output

The output of Fold::fold, Self will replace all instances of T in an expression by values of this type.
Source§

fn fold(&mut self, _: &Rem<L, R>) -> <U as Fold<Rem<L, R>>>::Output

perform the replacement
Source§

impl<L, R, U> Fold<Shl<L, R>> for U
where U: Fold<L> + Fold<R>, L: Foldable<U>, R: Foldable<U>, <L as Foldable<U>>::Output: Shl<<R as Foldable<U>>::Output>,

Source§

type Output = <<L as Foldable<U>>::Output as Shl<<R as Foldable<U>>::Output>>::Output

The output of Fold::fold, Self will replace all instances of T in an expression by values of this type.
Source§

fn fold(&mut self, _: &Shl<L, R>) -> <U as Fold<Shl<L, R>>>::Output

perform the replacement
Source§

impl<L, R, U> Fold<Shr<L, R>> for U
where U: Fold<L> + Fold<R>, L: Foldable<U>, R: Foldable<U>, <L as Foldable<U>>::Output: Shr<<R as Foldable<U>>::Output>,

Source§

type Output = <<L as Foldable<U>>::Output as Shr<<R as Foldable<U>>::Output>>::Output

The output of Fold::fold, Self will replace all instances of T in an expression by values of this type.
Source§

fn fold(&mut self, _: &Shr<L, R>) -> <U as Fold<Shr<L, R>>>::Output

perform the replacement
Source§

impl<L, R, U> Fold<Sub<L, R>> for U
where U: Fold<L> + Fold<R>, L: Foldable<U>, R: Foldable<U>, <L as Foldable<U>>::Output: Sub<<R as Foldable<U>>::Output>,

Source§

type Output = <<L as Foldable<U>>::Output as Sub<<R as Foldable<U>>::Output>>::Output

The output of Fold::fold, Self will replace all instances of T in an expression by values of this type.
Source§

fn fold(&mut self, _: &Sub<L, R>) -> <U as Fold<Sub<L, R>>>::Output

perform the replacement
Source§

impl<T, U> Fold<Xpr<T>> for U
where U: Fold<T>, T: Foldable<U>,

Source§

type Output = <T as Foldable<U>>::Output

The output of Fold::fold, Self will replace all instances of T in an expression by values of this type.
Source§

fn fold(&mut self, _: &Xpr<T>) -> <T as Foldable<U>>::Output

perform the replacement
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.