Skip to content

Commit

Permalink
bring back FunctionalSequence
Browse files Browse the repository at this point in the history
  • Loading branch information
baloo committed Mar 4, 2024
1 parent f3cbc52 commit acd6e97
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
81 changes: 81 additions & 0 deletions src/functional.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//! Functional programming with [`Array`]s.

use crate::{Array, ArraySize};

/// Defines functional programming methods for [`Array`]s.
pub trait FunctionalSequence<T, U> {
/// Maps an `Array` to another `Array`
///
/// If the mapping function panics, any already initialized elements in the new array will
/// be dropped, AND any unused elements in the source array will also be dropped.
fn map<O, F>(self, f: F) -> Array<O, U>
where
U: ArraySize,
F: FnMut(T) -> O;

/// Combines two `Array` instances and iterates through both of them, initialization a new
/// `Array` with the result of the zipped mapping function.
///
/// If the mapping function panics, any already initialized elements in the new array will
/// be dropped, AND any unused elements in the source arrays will also be dropped.
fn zip<Rhs, F, O>(self, rhs: Array<Rhs, U>, f: F) -> Array<O, U>
where
U: ArraySize,
F: FnMut(T, Rhs) -> O;

/// Folds (or reduces) a sequence of data into a single value.
///
/// If the fold function panics, any unused elements will be dropped.
fn fold<O, F>(self, init: O, f: F) -> O
where
F: FnMut(O, T) -> O;
}

impl<T, U> FunctionalSequence<T, U> for Array<T, U>
where
U: ArraySize,
{
#[inline(always)]
fn map<O, F>(self, mut f: F) -> Array<O, U>
where
F: FnMut(T) -> O,
{
let mut out = Array::uninit();

for (i, s) in self.into_iter().enumerate() {
out[i].write(f(s));
}

unsafe { out.assume_init() }
}

#[inline(always)]
fn zip<Rhs, F, O>(self, rhs: Array<Rhs, U>, mut f: F) -> Array<O, U>
where
U: ArraySize,
F: FnMut(T, Rhs) -> O,
{
let mut out = Array::uninit();

let mut s = self.into_iter().enumerate();
let mut r = rhs.into_iter();

while let (Some((i, s)), Some(r)) = (s.next(), r.next()) {
out[i].write(f(s, r));
}

unsafe { out.assume_init() }
}

#[inline(always)]
fn fold<O, F>(self, mut init: O, mut f: F) -> O
where
F: FnMut(O, T) -> O,
{
for t in self {
init = f(init, t)
}

init
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
extern crate std;

mod from_fn;
pub mod functional;
mod iter;
mod sizes;
mod traits;
Expand Down

0 comments on commit acd6e97

Please sign in to comment.