1124-listfilter-select-elements-by-predicate — List.filter: Select Elements by Predicate
Functional Programming
Tutorial
The Problem
filter selects elements from a collection that satisfy a predicate, discarding the rest. It is the second pillar of functional data processing (alongside map and fold), appearing in every query language, data pipeline, and UI list filtering operation.
OCaml's List.filter and Rust's Iterator::filter both express this operation, but with different evaluation models and memory characteristics.
🎯 Learning Outcomes
Iterator::filter with a predicate closure to select elementsList.filter structurefilter with map in a pipelinefilter (returns references) and filter_map (transforms while filtering)Code Example
#![allow(clippy::all)]
//! Stub to satisfy cargo.
pub fn stub() {}Key Differences
iter().filter(|&&x| ...) requires double dereference due to the reference layer added by iter; using iter().copied().filter(|&x| ...) or iter().filter(|x| **x % 2 == 0) are alternatives.filter is lazy — it does not evaluate until consumed; OCaml's List.filter traverses the list immediately.filter_map**: Rust provides filter_map(|x| ...) for combined filter+transform; OCaml has List.filter_map in Base (not stdlib).Vec after .collect(); OCaml's List.filter builds a new linked list.OCaml Approach
let rec filter f = function
| [] -> []
| x :: rest -> if f x then x :: filter f rest else filter f rest
(* Standard library version *)
let filter_evens lst = List.filter (fun x -> x mod 2 = 0) lst
OCaml's List.filter traverses the list once, building a new list with only matching elements.
Full Source
#![allow(clippy::all)]
//! Stub to satisfy cargo.
pub fn stub() {}Exercises
partition_by<T, F: Fn(&T) -> bool>(list: &[T], pred: F) -> (Vec<T>, Vec<T>) using Iterator::partition.filter_map_result<T, E, F: Fn(T) -> Result<T, E>>(list: Vec<T>, f: F) -> (Vec<T>, Vec<E>).filter and map to extract all valid email domains from a list of strings: filter valid emails, map to extract the domain after @.