I have some functions written in C that I call from Haskell. These functions return IO (CInt). Sometimes I want to run all of the functions regardless of what any of them return, and this is easy. For sake of example code, this is the general idea of what's happening currently:
Prelude> let f x = print x >> return x
Prelude> mapM_ f [0..5]
0
1
2
3
4
5
Prelude>
I get my desired side effects, and I don't care about the results. But now I need to stop execution immediately after the first item that doesn't return my desired result. Let's say a return value of 4 or higher requires execution to stop - then what I want to do is this:
Prelude> takeWhile (<4) $ mapM f [0..5]
Which gives me this error:
<interactive>:1:22:
Couldn't match expected type `[b]' against inferred type `IO a'
In the first argument of `mapM', namely `f'
In the second argument of `($)', namely `mapM f ([0 .. 5])'
In the expression: takeWhile (< 4) $ mapM f ([0 .. 5])
And that makes sense to me - the result is still contained in the IO monad, and I can't just compare two values contained in the IO monad. I know this is precisely the purpose of monads -- chaining results together and discarding operations when a certain condition is met -- but is there an easy way to "wrap up" the IO monad in this case to stop executing the chain upon a condition of my choosing, without writing an instance of MonadPlus?
Can I just "unlift" the values from f, for the purposes of the takeWhile?
Is this a solution where functors fit? Functors haven't "clicked" with me yet, but I sort of have the impression that this might be a good situation to use them.
Update:
@sth has the closest answer to what I want - in fact, that's almost exactly what I was going for, but I'd still like t