Crossing Monads in Haskell

I'm really new to Haskell, so this might be a dumb question. I have a function

foo :: Int -> IO () 

the result of which will print some useful information. Now I want to do this:

 do foo 0 foo 1 foo 0 foo 2 foo 3 

How can I write this as a loop? My problem is to "concatenate" Monads, which is done automatically with the do statement ...

Thank you for your help!

+8
haskell
source share
2 answers

mapM_ foo [0,1,0,2,3] will do the trick.

What could be more important, "how to understand this?" Hoogle is a great tool. You want to apply a function with the signature Int -> IO () to the Int set to get a new I / O action. So you have a signature (Int -> IO ()) -> [Int] -> IO () , so we are looking to request Hoogle for functions with this signature . Second result: mapM_ , whose signature

 Monad m => (a -> mb) -> [a] -> m () 

That's right, that's why mapM_ actually works with any monad (not just IO ) and any type (and not just Int ). When you think about it, this is not surprising.

+14
source share

You need the mapM_ combinator, which displays a function that returns a monadic value in a list and uses the binding operator to sequence the results:

 >> let foo n = putStrLn (show n ++ "!") >> mapM_ foo [0,1,0,2,3] 0! 1! 0! 2! 3! 

Sometimes people like to use the inverted version.

 for :: Monad m => [a] -> (a -> mb) -> m () for = flip mapM_ 

which is more like an imperative code:

 >> for [1..5] $ \n -> putStrLn ("Number: " ++ show n) Number: 1 Number: 2 Number: 3 Number: 4 Number: 5 

Note that the combinator named forM_ is defined in Control.Monad and does the same thing as the combinator that I called for .

+12
source share

All Articles