我的Haskell程序太懒了

时间:2016-07-26 07:05:50

标签: haskell lazy-evaluation

我的功能如下:

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工作?

如何让我的函数回调更可靠?

1 个答案:

答案 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"