我正在看这里的信息:Hackage
我想在我的程序中发生不同的事情,具体取决于按下了哪个箭头键。使用NCurses模块,我可以使用getEvent函数注册一个事件。但我无法让我的if语句处理存储的事件。这是我的代码:
main = runCurses $ do
w <- defaultWindow
e <- getEvent w (Just 300)
let x = setX e
setX e
| e == KeyLeftArrow = -1
| e == KeyRightArrow = 1
| otherwise = 0
这给了Couldn't match expected type ‘Key’ with actual type ‘Maybe Event’
所以我改为e == Just Key...Arrow
然后得到
Couldn't match type ‘Event’ with ‘Key’
Expected type: Maybe Key
Actual type: Maybe Event
我想这是因为e
是一个事件,我表现得好像它是一个Key,但即使在尝试这个Key e == Just Key...Arrow
后它也无法正常工作。如何将此事件转换为密钥?或者以其他方式只是能够让我的e
条件工作?
看看getEvent
的定义
getEvent
:: Window
-> Maybe Integer
-> Curses (Maybe Event)
你可能会注意到它返回包裹在Maybe Event
monad中的Curses
。在setX
函数中,您正在尝试将事件与键进行比较。编译器说你确切地说这个不匹配:
Couldn't match type ‘Event’ with ‘Key’
Expected type: Maybe Key
Actual type: Maybe Event
让我们去文档,找到更多关于Event
和Key
类型的信息。以下是Event
的定义:
data Event
= EventCharacter Char
| EventSpecialKey Key
| EventMouse Integer MouseState
| EventResized
| EventUnknown Integer
您可能会注意到Event
有几个变体(构造函数),其中一个EventSpecialKey
包裹Key
。这正是你所需要的。
setX e
| e == Just (EventSpecialKey KeyLeftArrow) = -1
| e == Just (EventSpecialKey KeyRightArrow) = 1
| otherwise = 0
您已正确识别问题。你提出的将Key
放在等于左边的解决方案是断言你有一把钥匙,当你已经确定你实际上没有钥匙时!
看包装链接显示Event
可能是一个按键EventSpecialKey Key
。从而,
setX e = case e of --lambdacase would be even more idiomatic
Just (EventSpecialKey KeyLeftArrow) -> -1
Just (EventSpecialKey KeyRightArrow) -> 1
_ -> 0