surmonter
surmonter

Reputation: 19

">>=" operator and "map" function

I have a working code from the example of the openbrowser library.

import Web.Browser (openBrowser)
main :: IO ()
main = openBrowser "http://haskell.org/" >>= print

What I would like to do is to open two websites.

So I was think doing something like:

main = map openBrowser ["http://haskell.org/","http://google.com/"] >>= print

And I would get

Couldn't match type ‘[]’ with ‘IO’
Expected type: IO (IO Bool)
Actual type: [IO Bool]

But I have a very hard time figuring out what is the proper way to call this >>= print command if I use map.

Upvotes: 1

Views: 1323

Answers (1)

Random Dev
Random Dev

Reputation: 52280

using forM

In this case I would use forM_:

main = 
    forM_ ["http://haskell.org/","http://google.com/"] (openBrowser >=> print)

which you can use to repeat an a -> IO b action for each item in an list [a] and get an IO () (the result of the action will be discarded - with the forM_ version which is what we want as it should be our main so it has to be IO () - the forM version would yield IO [()] instead)

using mapM

or if you want to stick closer to your idea you can use map mapM_ instead:

main = 
    mapM_ (openBrowser >=> print) ["http://haskell.org/","http://google.com/"]

which is just forM_ with the arguments flipped - the type-explanation is just the same.

using sequence

the reason yours does not work is that openBrowswer will return an IO Bool action (or so it seems based on the error message) and so the map will return an [IO Bool] but to use (>>=) you need some IO a

So you would need to first collapse the list into one IO action (which can be done with sequence :: [IO a] -> IO [a]):

main = 
    sequence (map openBrowser ["http://haskell.org/","http://google.com/"]) >>= print

which should print an list [True, True] hopefully


But I think what you really wanted to do is to open the site and print the result for each (on a newline without the list brackets)

Upvotes: 4

Related Questions