我的功能如下:
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 ()
这是我的应用中使用的回调。
此功能似乎无法触发,因为没有任何putStrLn打印到控制台。
但是这个功能 - 只需稍作修改即可将所有内容打印到控制台:
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 ()
为什么SDL.EventPayload
的完整评估会导致周围的putStrLn
工作?
如何让我的函数回调更可靠?
答案 0 :(得分:1)
正如Thomas在评论中指出的那样,这看起来像是一个缓冲问题。 System.IO
包描述了标准buffering behavior。
您有几种方法可以解决此类问题。您可以使用以下方法在程序中手动设置缓冲模式:
hSetBuffering stdout NoBuffering
在你的功能开始。这将关闭所有缓冲(您也可以选择LineBuffering
)并立即打印到stdout。
您还可以在每次打印后刷新缓冲区:
SDL.MouseMotionEvent dat -> do
liftIO $ putStrLn "HELLO"
hFlush stdout
或者您可以尝试直接打印到具有不同默认缓冲规则的stderr
句柄:
SDL.MouseMotionEvent dat -> do
liftIO $ hPutStrLn stderr "HELLO"