Skip to content

Commit

Permalink
feat: FoldAdd and FoldMul (#209)
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel-Aaron-Bloom authored Feb 18, 2025
1 parent 2488205 commit e5dffdd
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ against this Rust version.
- [added] Playground metadata
- [changed] Remove build scripts; instead check-in the built code
- [added] Constants for 3600
- [added] `FoldAdd` and `FoldMul` to get the sum/product of an array

### 1.16.0 (2022-12-05)
- [added] `const INT` field to the `ToInt` trait.
Expand Down
54 changes: 54 additions & 0 deletions src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,60 @@ where
}
}

// ---------------------------------------------------------------------------------------
// FoldAdd

/// Hide our `Null` type
const _: () = {
/// A type which contributes nothing when adding (i.e. a zero)
pub struct Null;
impl<T> Add<T> for Null {
type Output = T;
fn add(self, rhs: T) -> Self::Output {
rhs
}
}

impl FoldAdd for ATerm {
type Output = Null;
}
};

impl<V, A> FoldAdd for TArr<V, A>
where
A: FoldAdd,
FoldSum<A>: Add<V>,
{
type Output = Sum<FoldSum<A>, V>;
}

// ---------------------------------------------------------------------------------------
// FoldMul

/// Hide our `Null` type
const _: () = {
/// A type which contributes nothing when multiplying (i.e. a one)
pub struct Null;
impl<T> Mul<T> for Null {
type Output = T;
fn mul(self, rhs: T) -> Self::Output {
rhs
}
}

impl FoldMul for ATerm {
type Output = Null;
}
};

impl<V, A> FoldMul for TArr<V, A>
where
A: FoldMul,
FoldProd<A>: Mul<V>,
{
type Output = Prod<FoldProd<A>, V>;
}

// ---------------------------------------------------------------------------------------
// Add arrays
// Note that two arrays are only addable if they are the same length.
Expand Down
8 changes: 7 additions & 1 deletion src/operator_aliases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// Aliases!!!
use crate::type_operators::{
Abs, Cmp, Gcd, Len, Logarithm2, Max, Min, PartialDiv, Pow, SquareRoot,
Abs, Cmp, FoldAdd, FoldMul, Gcd, Len, Logarithm2, Max, Min, PartialDiv, Pow, SquareRoot,
};
use core::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Rem, Shl, Shr, Sub};

Expand Down Expand Up @@ -83,6 +83,12 @@ pub type Compare<A, B> = <A as Cmp<B>>::Output;
/// Alias for the associated type of `Len`: `Length<A> = <A as Len>::Output`
pub type Length<T> = <T as Len>::Output;

/// Alias for the associated type of `FoldAdd`: `FoldSum<A> = <A as FoldAdd>::Output`
pub type FoldSum<A> = <A as FoldAdd>::Output;

/// Alias for the associated type of `FoldMul`: `FoldProd<A> = <A as FoldMul>::Output`
pub type FoldProd<A> = <A as FoldMul>::Output;

/// Alias for the associated type of `Min`: `Minimum<A, B> = <A as Min<B>>::Output`
pub type Minimum<A, B> = <A as Min<B>>::Output;

Expand Down
19 changes: 19 additions & 0 deletions src/type_operators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,25 @@ pub trait Len {
fn len(&self) -> Self::Output;
}

/// A **type operator** that gives the sum of all elements of an `Array`.
pub trait FoldAdd {
/// The type of the result of the sum
type Output;
}

/// A **type operator** that gives the product of all elements of an `Array`.
pub trait FoldMul {
/// The type of the result of the product
type Output;
}

#[test]
fn fold_test() {
use crate::*;
assert_eq!(10, <FoldSum::<tarr![U2, U3, U5]>>::to_u32());
assert_eq!(30, <FoldProd::<tarr![U2, U3, U5]>>::to_u32());
}

/// Division as a partial function. This **type operator** performs division just as `Div`, but is
/// only defined when the result is an integer (i.e. there is no remainder).
pub trait PartialDiv<Rhs = Self> {
Expand Down

0 comments on commit e5dffdd

Please sign in to comment.