There is a library that provides a data type
F and a function of type
ffoldlIO :: (b -> a -> IO b) -> b -> F a -> IO b
The function is similar to
foldlIO :: (b -> a -> IO b) -> b -> [a] -> IO b foldlIO f a = \xs -> foldr (\x r (!a') -> f a' x >>= r) return xs a
I wonder whether
foldlIO (and thus
ffoldlIO) can run in a short-circuit fashion.
Consider this example:
example1 :: IO Int example1 = foldlIO (\a x -> if a < 4 then return (a + x) else return a) 0 [1..5]
foldlIO traverses the entire list, but what if we throw an exception to stop the computation and then catch it? Something like this:
data Terminate = Terminate deriving (Show) instance Exception Terminate example2 :: IO Int example2 = do ra <- newIORef 0 let step a x | a' < 4 = return a' | otherwise = writeIORef ra a' >> throwIO Terminate where a' = a + x foldlIO step 0 [1..] `catch` \(_ :: Terminate) -> readIORef ra
Is this reliable? Is there a better way to terminate a computation that runs in the
IO monad (and no other monad) or am I not supposed to do this at all?