// 001: Higher-Order Functions
// map, filter, fold — the three pillars of functional programming
// Approach 1: Using iterator methods
fn double_all(nums: &[i32]) -> Vec<i32> {
nums.iter().map(|&x| x * 2).collect()
}
fn evens(nums: &[i32]) -> Vec<i32> {
nums.iter().filter(|&&x| x % 2 == 0).copied().collect()
}
fn sum(nums: &[i32]) -> i32 {
nums.iter().fold(0, |acc, &x| acc + x)
}
// Approach 2: Manual recursive implementations
fn my_map(f: fn(i32) -> i32, slice: &[i32]) -> Vec<i32> {
if slice.is_empty() {
vec![]
} else {
let mut result = vec![f(slice[0])];
result.extend(my_map(f, &slice[1..]));
result
}
}
fn my_filter(pred: fn(i32) -> bool, slice: &[i32]) -> Vec<i32> {
if slice.is_empty() {
vec![]
} else {
let mut result = if pred(slice[0]) { vec![slice[0]] } else { vec![] };
result.extend(my_filter(pred, &slice[1..]));
result
}
}
fn my_fold(f: fn(i32, i32) -> i32, acc: i32, slice: &[i32]) -> i32 {
if slice.is_empty() {
acc
} else {
my_fold(f, f(acc, slice[0]), &slice[1..])
}
}
// Approach 3: Chained iterators
fn sum_of_doubled_evens(nums: &[i32]) -> i32 {
nums.iter()
.filter(|&&x| x % 2 == 0)
.map(|&x| x * 2)
.sum()
}
fn main() {
let nums: Vec<i32> = (1..=10).collect();
println!("double_all([1,2,3]) = {:?}", double_all(&[1, 2, 3]));
println!("evens(1..10) = {:?}", evens(&nums));
println!("sum(1..10) = {}", sum(&nums));
println!("sum_of_doubled_evens(1..10) = {}", sum_of_doubled_evens(&nums));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_double_all() {
assert_eq!(double_all(&[1, 2, 3]), vec![2, 4, 6]);
}
#[test]
fn test_evens() {
let nums: Vec<i32> = (1..=10).collect();
assert_eq!(evens(&nums), vec![2, 4, 6, 8, 10]);
}
#[test]
fn test_sum() {
let nums: Vec<i32> = (1..=10).collect();
assert_eq!(sum(&nums), 55);
}
#[test]
fn test_my_map() {
assert_eq!(my_map(|x| x + 1, &[1, 2, 3]), vec![2, 3, 4]);
}
#[test]
fn test_my_filter() {
assert_eq!(my_filter(|x| x > 3, &[1, 2, 3, 4, 5]), vec![4, 5]);
}
#[test]
fn test_my_fold() {
assert_eq!(my_fold(|a, b| a + b, 0, &[1, 2, 3]), 6);
}
#[test]
fn test_sum_of_doubled_evens() {
let nums: Vec<i32> = (1..=10).collect();
assert_eq!(sum_of_doubled_evens(&nums), 60);
}
}
(* 001: Higher-Order Functions *)
(* map, filter, fold — the three pillars of functional programming *)
(* Approach 1: Using standard library functions *)
let double_all lst = List.map (fun x -> x * 2) lst
let evens lst = List.filter (fun x -> x mod 2 = 0) lst
let sum lst = List.fold_left (fun acc x -> acc + x) 0 lst
(* Approach 2: Manual recursive implementations *)
let rec my_map f = function
| [] -> []
| x :: xs -> f x :: my_map f xs
let rec my_filter pred = function
| [] -> []
| x :: xs ->
if pred x then x :: my_filter pred xs
else my_filter pred xs
let rec my_fold_left f acc = function
| [] -> acc
| x :: xs -> my_fold_left f (f acc x) xs
(* Approach 3: Composition — combine HOFs *)
let sum_of_doubled_evens lst =
lst
|> List.filter (fun x -> x mod 2 = 0)
|> List.map (fun x -> x * 2)
|> List.fold_left ( + ) 0
(* Tests *)
let () =
let nums = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10] in
assert (double_all [1; 2; 3] = [2; 4; 6]);
assert (evens nums = [2; 4; 6; 8; 10]);
assert (sum nums = 55);
assert (my_map (fun x -> x + 1) [1; 2; 3] = [2; 3; 4]);
assert (my_filter (fun x -> x > 3) [1; 2; 3; 4; 5] = [4; 5]);
assert (my_fold_left ( + ) 0 [1; 2; 3] = 6);
assert (sum_of_doubled_evens nums = 60);
Printf.printf "✓ All tests passed\n"