To answer the question about Haskell, you need to specify what you mean with Iterator
in the context of Haskell. AFAIK, usually you operate on data structures directly via higher order functions, you don’t need some of the things that Rust’s iterators offer like not iterating the whole list (lazyness got you covered), or mutating things (mutation won’t usually happen in Haskell’s data structures). For performance, turning multiple operations into a single tight loop, there’s optimizations called “fusion” that are utilized by some libraries.
The iteration API for data structures revolves around the type classes (i.e. traits) Functor
, Foldable
, and Traversable
. The main function from Traversable
, traverse
allows iteration with monadic effects like errors. (Edit: By “iteration” I mean a map
operation in the previous sentence; traverse
is also aliased as mapM
with a (for historic reasons and possibly performance reasons) slightly less general type.) But these type classes don’t offer generic approaches for stuff like filter
ing. For these kind of operations there is usually an API inspired by the standard libraries Data.List
’s API that other list-like types reproduce. These usually include monadic variants of all kinds of operations.
Lets look at the types of filter
on lists and its monadic variant filterM
in detail:
filter :: (a -> Bool) -> [a] -> [a]
could be translated into Rust syntax
fn filter<A>(f: impl Fn(A) -> bool, l: List<A>) -> List<A>
And filterM
(in the module Control.Monad)
filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]
is something you can’t translate into Rust directly, since Rust doesn’t support traits with higher-kinded types (i.e. types that take Parameters) as Self
. Monad
is such a trait. If Rust did support those, it would perhaps look like
fn filterM<M: Monad, A>(f: impl Fn(A) -> M<bool>, l: List<A>) -> M<List<A>>
In particular you can apply filterM
as if it had the type
filterM :: (a -> Either e Bool) -> [a] -> Either e [a]
or
filterM :: (a -> Maybe Bool) -> [a] -> Maybe [a]
since both Either e
and Maybe
are instances of (i.e. they implement) Monad
.
These type signatures could be translated as:
fn filterM<E, A>(f: impl Fn(A) -> Result<bool, E>, l: List<A>) -> Result<List<A>, E>
and
fn filterM<A>(f: impl Fn(A) -> Option<bool>, l: List<A>) -> Option<List<A>>