我的 Haskell 程序太懒了
My Haskell program is too lazy
我的函数如下:
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 的 none 打印到控制台。
但是这个函数 - 稍作修改就可以将所有内容打印到控制台:
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
起作用?
如何使我的函数回调更加可靠?
为Thomas pointed out in the comments, this looks like a buffering problem. The System.IO
package describes standard buffering behavior。
关于如何解决此类问题,您有多种选择。您可以在程序中手动设置缓冲模式:
hSetBuffering stdout NoBuffering
在函数的开头。这将关闭所有缓冲(您也可以选择 LineBuffering
)并立即打印到标准输出。
您还可以在每次打印后刷新缓冲区:
SDL.MouseMotionEvent dat -> do
liftIO $ putStrLn "HELLO"
hFlush stdout
或者您可以尝试直接打印到具有不同默认缓冲规则的 stderr
句柄:
SDL.MouseMotionEvent dat -> do
liftIO $ hPutStrLn stderr "HELLO"
我的函数如下:
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 的 none 打印到控制台。
但是这个函数 - 稍作修改就可以将所有内容打印到控制台:
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
起作用?
如何使我的函数回调更加可靠?
为Thomas pointed out in the comments, this looks like a buffering problem. The System.IO
package describes standard buffering behavior。
关于如何解决此类问题,您有多种选择。您可以在程序中手动设置缓冲模式:
hSetBuffering stdout NoBuffering
在函数的开头。这将关闭所有缓冲(您也可以选择 LineBuffering
)并立即打印到标准输出。
您还可以在每次打印后刷新缓冲区:
SDL.MouseMotionEvent dat -> do
liftIO $ putStrLn "HELLO"
hFlush stdout
或者您可以尝试直接打印到具有不同默认缓冲规则的 stderr
句柄:
SDL.MouseMotionEvent dat -> do
liftIO $ hPutStrLn stderr "HELLO"