It’s been a Haskell programming rule of mine for a long time
that explicit recursion is an admission of failure. First,
linear recursions have already been captured in one of the
Prelude (or Data.List) functions. Second, recursions or
iterations over a data structure are almost always either fmap
or one of the Data.Foldable functions. Third, the list monad
(and list comprehensions) capture a common recursion pattern,
one found especially in path-finding, alpha-beta AI, and other
try-every-path problem spaces. If you’re recursing, and lists
are involved, the recursion pattern has already been captured in
a Prelude or Data.List function. map, the fold*s, the scan*s,
filter, find, unfoldr and group(By) cover, I think, every loop
I’ve ever written in an imperative language. The dynamic
“scripting” languages like Perl and Python have had foreach
loops for years, to cover the most common case of looping over
every element of an array. Java 1.6 and C# have this too. That’s
a handy bit of syntactic sugar, but it is o