What is a simple way to wait for and then detect keypresses in Haskell?

风流意气都作罢 提交于 2019-12-05 02:41:42

If you don't want blocking you can use hReady to detect whether a key has been pressed yet. This is useful for games where you want the program to run and pick up a key press whenever it has happened without pausing the game.

Here's a convenience function I use for this:

ifReadyDo :: Handle -> IO a -> IO (Maybe a)
ifReadyDo hnd x = hReady hnd >>= f
   where f True = x >>= return . Just
         f _    = return Nothing

Which can be used like this:

stdin `ifReadyDo` getChar

Returning a Maybe that is Just if a key was pressed and Nothing otherwise.

import System.IO

main :: IO ()
main = do
  hSetBuffering stdin NoBuffering
  x <- getChar
  putStrLn ("You pressed: " ++ [x])

I don't know when this is guaranteed to work. Putting the terminal into a "raw" mode is a system-dependent process. But it works for me with GHC 6.12.1 on Linux.

You can use getChar instead of getLine. This probably isn't what you're looking for, but it's the simplest way.

pressKey :: IO ()
pressKey = do x <- getChar
              return x

But there's an even simpler way. Just write getChar:

pressKey :: IO ()
pressKey = getChar >> putStr "I am a String"

pressKey = putStrLn "Hi" >> getChar >> putStrLn "Bye"
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!