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"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With