For sequencing in Haskell, you have the functions >>= and sequence :
(>>=) :: Monad m => ma -> (a -> mb) -> mb sequence :: Monad m => [ma] -> m [a]
The >>= function or bind performs a monadic action, extracts a value from it, and passes it to a function that returns a new monadic action. The sequence function takes a list of monadic actions of the same type and performs them all, aggregating their results and wrapping them as one action.
For iteration, you have mapM and forM ( forM = flip mapM )
mapM :: Monad m => (a -> mb) -> [a] -> m [b]
The mapM and forM are designed to use a function that returns an action to each item in the list, aggregating the results as a single action.
For choice, I assume that you mean conditional expressions that are implemented in Haskell as if-else-else expressions. They can be used directly in monadic expressions, just as they can be used in pure expressions. However, you can also use certain monads to make choices, or at least handle errors. The easiest way is the Maybe monad:
data Maybe a = Nothing | Just a instance Monad Maybe where return a = Just a (Just a) >>= f = fa Nothing >>= f = Nothing
It has a very simple implementation. Essentially, if you try to arrange Nothing for something else, it will return Nothing every time. This gives you an idea of a short circuit:
lookup :: Eq a => a -> [(a, b)] -> Maybe b -- Looks up a value in a key-value association list myFunc :: Int -> [(String, Int)] -> Maybe Int myFunc mult assocList = do i <- lookup "foo" assocList j <- lookup "bar" assocList return $ i * mult + j
Here, if the search for "foo" fails, myFunc immediately returns Nothing . Similarly, if the search for "bar" not performed, myFunc immediately returns Nothing . This only happens when both searches successfully perform any calculations on myFunc . This provides some kind of error handling. There's a similar monad Either a
data Either ab = Left a | Right b instance Monad (Either a) where return a = Right a (Right a) >>= f = fa (Left a) >>= f = Left a
which works very well, except that the value "failure" may carry some kind of context, such as a string error message or a calculation state at the point of failure.