# Haskell function that executes each action until a predicate returns True

The following function executes each action from the list until a predicate returns True. I have a feeling that this function can be rewritten using fold and without the do construct but I don't know how.

execUntil :: (Eq a, Monad m) => [m a] -> (a -> Bool) -> m ()
execUntil [] p = return ()
execUntil (a:as) p = do
r <- a
if p r then return () else execUntil as p

• Not sure if this is a question that fits more into stackoverflow. Your code works.. but you're asking how to do a specific thing. Jul 19, 2022 at 18:21
• I'm kind of asking for advice on how to improve my code that works. Isn't a code review about it? Jul 19, 2022 at 18:57
• That's why I'm not sure Jul 19, 2022 at 19:08
• Since foldM is a left fold, I don't think you can use it for this. You also can't use a non-monadic fold. execUntil is called whileM in Control.Monad.Extra and Control.Monad.Loops, implemented with when rather than if/then/else but otherwise the same. It will still do recursion under the hood but there's no way around this. Jul 19, 2022 at 19:28

import Control.Monad (void)
execUntil = flip $\p -> void . foldl (\ma mb -> ma >>= bool (p <$> mb) (pure True)) (pure False)

I wouldn't recommend it, though. foldl doesn't have any way to short-circuit, so this implementation will traverse the entire [m a], even beyond when the a -> Bool predicate is satisfied.
IMO, the code you've provided is totally fine as-is! Except perhaps for the unnecessary Eq a constraint ;p