6 Functional Programming

6.1 FP for Vector

  • There are some functional programming tools for Vec<f64>

    pub trait FPVector {
        type Scalar;
    
        fn fmap<F>(&self, f: F) -> Self
        where
            F: Fn(Self::Scalar) -> Self::Scalar;
        fn reduce<F, T>(&self, init: T, f: F) -> Self::Scalar
        where
            F: Fn(Self::Scalar, Self::Scalar) -> Self::Scalar,
            T: convert::Into<Self::Scalar>;
        fn zip_with<F>(&self, f: F, other: &Self) -> Self
        where
            F: Fn(Self::Scalar, Self::Scalar) -> Self::Scalar;
        fn filter<F>(&self, f: F) -> Self
        where
            F: Fn(Self::Scalar) -> bool;
        fn take(&self, n: usize) -> Self;
        fn skip(&self, n: usize) -> Self;
    }

6.1.1 fmap

  • fmap is syntactic sugar for map

  • But different to original map - Only f64 -> f64 allowed.

    fn main() {
        let a = c!(1,2,3,4);
    
        // Original rust
        a.clone()
            .into_iter()
            .map(|x| x + 1f64)
            .collect::<Vec<f64>>()
            .print();
            // [2, 3, 4, 5]
    
        // fmap in Peroxide
        a.fmap(|x| x + 1f64).print();
        // [2, 3, 4, 5]
    }

6.1.2 reduce

  • reduce is syntactic sugar for fold

    fn main() {
        let a = c!(1,2,3,4);
    
        // Original rust
        a.clone()
            .into_iter()
            .fold(0f64, |x, y| x + y)
            .print(); // 10
    
        // reduce in Peroxide
        a.reduce(0f64, |x, y| x + y).print(); // 10
    }

6.1.3 zip_with

  • zip_with is composed of zip & map

    fn main() {
        let a = c!(1,2,3,4);
        let b = c!(5,6,7,8);
    
        // Original rust
        a.clone()
            .into_iter()
            .zip(&b)
            .map(|(x, y)| x + *y)
            .collect::<Vec<f64>>().print();
            // [6, 8, 10, 12]
    
        // zip_with in Peroxide
        a.zip_with(|x, y| x + y, &b).print();
        // [6, 8, 10, 12]
    }