2010-10-08 24 views
9

Tôi khá mới với Haskell, vì vậy tôi đang tìm một cách đơn giản để phát hiện các phím bấm, thay vì sử dụng getLine.Cách đơn giản để chờ và sau đó phát hiện các phím bấm trong Haskell là gì?

Nếu có ai biết bất kỳ thư viện nào hoặc một số mẹo để thực hiện việc này, điều đó thật tuyệt vời!

Và nếu có một nơi tốt hơn để hỏi điều này, hãy hướng dẫn tôi ở đó, tôi sẽ đánh giá cao điều đó.

+0

Có một chủ đề tương tự tại đây http://stackoverflow.com/questions/2983974/haskell-read-input-character-from-console-immediately-not-after-newline –

+0

Hầu hết các thư viện GUI (ví dụ: gtk2hs) có một hoạt động kiểu onKeyPress - nếu bạn đang làm bất cứ điều gì lớn hay để phân phối thì hãy xem xét những thứ đó. –

Trả lời

14

Nếu bạn không muốn chặn bạn có thể sử dụng hReady để phát hiện xem một chìa khóa đã được ép được nêu ra. Điều này rất hữu ích cho các trò chơi mà bạn muốn chương trình chạy và nhận một lần nhấn phím bất cứ khi nào nó xảy ra mà không tạm dừng trò chơi.

Dưới đây là một chức năng thuận tiện tôi sử dụng cho việc này:

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

Mà có thể được sử dụng như thế này:

stdin `ifReadyDo` getChar 

Trả về một Maybe đó là Just nếu một phím được nhấn và Nothing khác.

+2

Tôi cũng đề cập đến chức năng' hSetEcho', cho phép chặn các ký tự lặp lại thành ' stdout', trong khi sử dụng 'getChar'. –

8
import System.IO 

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

Tôi không biết khi nào điều này được đảm bảo hoạt động. Đặt thiết bị đầu cuối vào chế độ "thô" là quá trình phụ thuộc vào hệ thống. Nhưng nó hoạt động với tôi với GHC 6.12.1 trên Linux.

+1

Nhưng nó không hoạt động trên Windows bằng GHC. –

+0

Đó là vấn đề tôi đã tìm thấy, nó hoạt động khá kém trên Windows, và yêu cầu một dòng mới trước khi nó được gửi. – TaslemGuy

-1

Bạn có thể sử dụng getChar thay vì getLine. Điều này có lẽ không phải là những gì bạn đang tìm kiếm, nhưng đó là cách đơn giản nhất.

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

Nhưng thậm chí còn có cách đơn giản hơn. Chỉ cần viết getchar:

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

pressKey = putStrLn "Hi" >> getChar >> putStrLn "Bye" 
+1

'Lần nhấn' đầu tiên của bạn chính xác tương đương với 'getChar' ở đây. –

+0

Vâng, tôi biết điều đó. Điểm của tôi là x có thể được sử dụng, ví dụ, "do {x <- getCbar; dosomething (đọc x :: Int)} hay không. – danportin

Các vấn đề liên quan