I think using &&
for conditional execution is a bit of a bad habit. Of course, it's just a matter of doing this for side effects such as False && all (/=0) [1..]
, but when there are side effects, it's pretty confusing to make them dependent in such a hidden way. (Since the practice is so widespread, most programmers will recognize it right away, but I donโt think that this is what we should encourage, at least not in Haskell.)
What you want is a way to express: "perform some action until you get False
."
For your simple example, I will just do it explicitly:
main = do e0 <- run "foo" when e0 $ run "bar"
or short: run "foo" >>= (`when` run "bar")
.
If you want to use it more widely, it is useful to do it in a more general way. Just checking the Boolean condition is not very general, you usually also want to pass some kind of result. Passing the results is the main reason why we use the monad for IO, and not just lists of primitive actions.
Yeah, monads! Indeed, you need the IO monad, but with the additional โkill switchโ: either you perform a sequence of actions, each of which may have some kind of result for the transfer, or - if any of them fails - you interrupt everything. Sounds the same as Maybe
, right?
http://www.haskell.org/hoogle/?hoogle=MaybeT
import Control.Monad.Trans.Maybe run :: String -> MaybeT IO () run s = MaybeT $ do e <- system s return $ if exitCodeToBool e then Just () else Nothing main = runMaybeT $ do run "foo" run "bar"
source share