简体   繁体   中英

My Haskell program is too lazy

I have a function like:

type App a = ExceptT AppError (ResourceT IO)

onEvent :: SDL.EventPayload -> App ()
onEvent event = do
  liftIO $ putStrLn "EVE!"
  case event of
    SDL.MouseMotionEvent dat -> do
      liftIO $ putStrLn "HELLO"
    SDL.KeyboardEvent kbe  -> liftIO $ putStrLn "WORLD"
    _ -> return ()

That is a callback being used in my app.

This function seemingly doesn't fire, Because none of the putStrLn's print to console.

But this function - with the slight modification does print everything to console:

onEvent :: SDL.EventPayload -> App ()
onEvent event = do
  liftIO $ putStrLn "EVE!"
  case event of
    SDL.MouseMotionEvent dat -> do
      liftIO $ print dat
    SDL.KeyboardEvent kbe  -> liftIO $ print kbe
    _ -> return ()

Why does the full evaluation of SDL.EventPayload cause the surrounding putStrLn 's to work?

How can I make my function callback a bit more reliable?

As Thomas pointed out in the comments, this looks like a buffering problem. The System.IO package describes standard buffering behavior .

You have a couple of options on how to resolve this kind of issue. You can manually set the buffering mode in your program with:

hSetBuffering stdout NoBuffering

at the beginning of your function. This will turn off all buffering (you could also choose LineBuffering ) and will print immediately to stdout.

You could also flush the buffer after every print:

SDL.MouseMotionEvent dat -> do
  liftIO $ putStrLn "HELLO"
  hFlush stdout

Or you can try to print directly to the stderr handle which has different default buffering rules:

SDL.MouseMotionEvent dat -> do
  liftIO $ hPutStrLn stderr "HELLO"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM