Reputation: 311
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?
Upvotes: 7
Views: 178
Reputation: 4517
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"
Upvotes: 1