func1, func2.. are all defined :: [String]-> Bool
will the following fold stop evaluating the functions as soon as the first true is hit
foldr (\x acc -> acc || x ) False ( fmap ($ "111") [func1,func2, func3, func4])
Thinking about it I realized the fmap will evaluate all 4 functions then pass a [Bool] to the fold.. which should stop fold as soon as it hits a True.
I guess the question I need to ask is if there is a way to merge the fmap into the fold so it stops evaluating as soon as one of the functions returns true.
A function like your
foldr (\x acc -> acc || x) False
has already been written for you. It is in the standard library under the name or
. Note that it flips the order of arguments to (||)
, which is necessary for the short-circuiting you want. So, you can simplify your problem to
or . map ($ "111") $ fs
And happily, the idea of mapping a function over a list and or
-ing together its results is also very common: witness any
. So we can rewrite your whole expression to
any ($ "111") fs
so that we don't have to worry at all about the details: the people who wrote any
were careful to not evaluate more of the list than necessary, so it's a solved problem from your point of view.
Your foldr
function uses ||
the wrong way around. You probably mean to write:
foldr (\x acc -> x || acc) False
Once you make that change, no, not all functions will be evaluated. You can see for yourself with Debug.Trace
main = print $ foldr (\x acc -> x || acc) False (fmap ($ True) [id, not, traceShowId, not])
This will print only one True
, showing that the third function in the list isn't forced.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.