Reputation: 19
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
Reputation: 52280
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)
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.
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