Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapping over IO in Haskell

Tags:

io

random

haskell

Is there a traditional way to map over a function that uses IO? Specifically, I'd like to map over a function that returns a random value of some kind. Using a normal map will result in an output of type ([IO b]), but to unpack the values in the list from IO, I need a something of type (IO [b]). So I wrote...

mapIO :: (a -> IO b) -> [a] -> [b] -> IO [b]
mapIO f [] acc = do return acc
mapIO f (x:xs) acc = do
  new <- f x
  mapIO f xs (new:acc)

... which works fine. But it seems like there ought to be a solution for this built into Haskell. For instance, an example use case:

getPercent :: Int -> IO Bool
getPercent x = do
  y <- getStdRandom (randomR (1,100))
  return $ y < x

mapIO (\f -> getPercent 50) [0..10] []
like image 501
unignorant Avatar asked Jul 01 '10 15:07

unignorant


1 Answers

The standard way is via:

Control.Monad.mapM :: (Monad m) => (a -> m b) -> [a] -> m [b]

which is implemented in terms of sequence:

sequence :: (Monad m) => [m a] -> m [a]
like image 128
Don Stewart Avatar answered Dec 07 '22 00:12

Don Stewart