Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collecting IO outputs into list

Tags:

io

haskell

monads

How can I issue multiple calls to SDL.pollEvent :: IO Event until the output is SDL.NoEvent and collect all the results into a list?

In imperative terms something like this:

events = []
event = SDL.pollEvent
while ( event != SDL.NoEvent ) {
        events.add( event )
        event = SDL.pollEvent
}
like image 277
user341228 Avatar asked May 16 '10 14:05

user341228


2 Answers

James Cook was so kind to extend monad-loops with this function:

unfoldWhileM  :: Monad  m => (a -> Bool) -> m a -> m [a]

used with SDL:

events <- unfoldWhileM (/= SDL.NoEvent) SDL.pollEvent
like image 152
Gerold Meisinger Avatar answered Sep 28 '22 00:09

Gerold Meisinger


You could use something like:

takeWhileM :: (a -> Bool) -> IO a -> IO [a]
takeWhileM p act = do
  x <- act
  if p x
    then do
      xs <- takeWhileM p act
      return (x : xs)
    else
      return []

Instead of:

do
  xs <- takeWhileM p act
  return (x : xs)

you can also use:

liftM (x:) (takeWhileM p act) yielding:

takeWhileM :: (a -> Bool) -> IO a -> IO [a]
takeWhileM p act = do
  x <- act
  if p x
    then liftM (x:) (takeWhileM p act)
    else return []

Then you can use: takeWhileM (/=SDL.NoEvent) SDL.pollEvent

like image 32
Peaker Avatar answered Sep 28 '22 00:09

Peaker