Purescript 无法从键盘获取键码
Purescript cannot get keycode from keyboard
我是函数式编程和 Purescript 的新手。我正在尝试从键盘按下的键获取键码。我制作了一个 eventListener,它在触发 keydown 事件时触发并触发事件侦听器功能测试。我在将事件转换为键盘事件并从键盘事件获取键码时遇到问题。我附上了我的代码并产生了错误。
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Class
import Control.Monad.Eff.Console (CONSOLE, log)
import DOM (DOM)
import DOM.Event.EventTarget (addEventListener, eventListener)
import DOM.HTML.Types as DHT
import DOM.Event.KeyboardEvent as KE
import DOM.Event.Types (EventType(..), EventTarget)
import DOM.Event.Event
import DOM.HTML (window)
import DOM.HTML.Window (document)
import Prelude (Unit)
test :: forall e. Event -> Eff ( console :: CONSOLE, dom :: DOM | e) Unit
test a = do
ke <- KE.eventToKeyboardEvent a
co <- KE.key ke
log "Key Pressed : "
main :: forall e. Eff (console :: CONSOLE, dom :: DOM | e) Unit
main = do
documenttarget <- liftEff $ window >>= document <#> DHT.htmlDocumentToEventTarget
addEventListener (EventType "keydown") (eventListener test) true (documenttarget)
错误:
Error found:
in module Main
at src/Main.purs line 30, column 10 - line 30, column 19
Could not match type
String
with type
t0 t1
while checking that type String
is at least as general as type t0 t1
while checking that expression key ke
has type t0 t1
in value declaration test
where t0 is an unknown type
t1 is an unknown type
See https://github.com/purescript/documentation/blob/master/errors/TypesDoNotUnify.md for more information,
or to contribute content related to this error.
* ERROR: Subcommand terminated with exit code 1
您的 test
函数需要稍微调整一下:
import Prelude
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Class (liftEff)
import Control.Monad.Eff.Console (CONSOLE, log)
import Control.Monad.Except (runExcept)
import DOM (DOM)
import DOM.Event.Event (Event)
import DOM.Event.EventTarget (addEventListener, eventListener)
import DOM.Event.KeyboardEvent as KE
import DOM.Event.Types (EventType(..))
import DOM.HTML (window)
import DOM.HTML.Types as DHT
import DOM.HTML.Window (document)
import Data.Either (Either(..))
test :: forall e. Event -> Eff ( console :: CONSOLE, dom :: DOM | e) Unit
test a =
case runExcept (KE.eventToKeyboardEvent a) of
Left err ->
log "Event was not a keyboard event"
Right ke -> do
let co = KE.key ke
log "Key Pressed : "
main :: forall e. Eff (console :: CONSOLE, dom :: DOM | e) Unit
main = do
documenttarget <- liftEff $ window >>= document <#> DHT.htmlDocumentToEventTarget
addEventListener (EventType "keydown") (eventListener test) true (documenttarget)
首先,KE.key
和 KE.eventToKeyboardEvent
不是有效函数,这意味着您无需绑定即可从中获取值(这就是 t0 t1
错误的原因关于:对于某些 m
).
,它期望结果值类似于 m String
而不仅仅是 String
接下来,当我们使用 eventToKeyboardEvent
时,它可能会失败,因为我们无法保证将任何 Event
强制转换为 KeyboardEvent
是安全的。结果包含在 F
, which is a synonym for Except MultipleErrors
中,所以我们需要做一些事情来获得结果。我们 "run" Except
包装器返回 Either
,其中 Left
端是错误消息,Right
是成功结果。
在这个例子中,我在转换失败时记录了它,但你可能不关心这个,通常甚至不希望这种情况被命中,在这种情况下使用 pure unit
是可能已经足够好了。
如果您愿意让失败案例什么都不做,实际上还有另一种写法:
import Data.Foldable (for_)
test :: forall e. Event -> Eff ( console :: CONSOLE, dom :: DOM | e) Unit
test a =
for_ (runExcept (KE.eventToKeyboardEvent a)) \ke -> do
let co = KE.key ke
log "Key Pressed : "
for_
实际上是一个高度通用的函数,可以用于各种各样的东西,但是这种使用它来静静地吸收失败的方法在编写代码以对抗丑陋的东西时非常方便 DOM API.
我是函数式编程和 Purescript 的新手。我正在尝试从键盘按下的键获取键码。我制作了一个 eventListener,它在触发 keydown 事件时触发并触发事件侦听器功能测试。我在将事件转换为键盘事件并从键盘事件获取键码时遇到问题。我附上了我的代码并产生了错误。
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Class
import Control.Monad.Eff.Console (CONSOLE, log)
import DOM (DOM)
import DOM.Event.EventTarget (addEventListener, eventListener)
import DOM.HTML.Types as DHT
import DOM.Event.KeyboardEvent as KE
import DOM.Event.Types (EventType(..), EventTarget)
import DOM.Event.Event
import DOM.HTML (window)
import DOM.HTML.Window (document)
import Prelude (Unit)
test :: forall e. Event -> Eff ( console :: CONSOLE, dom :: DOM | e) Unit
test a = do
ke <- KE.eventToKeyboardEvent a
co <- KE.key ke
log "Key Pressed : "
main :: forall e. Eff (console :: CONSOLE, dom :: DOM | e) Unit
main = do
documenttarget <- liftEff $ window >>= document <#> DHT.htmlDocumentToEventTarget
addEventListener (EventType "keydown") (eventListener test) true (documenttarget)
错误:
Error found:
in module Main
at src/Main.purs line 30, column 10 - line 30, column 19
Could not match type
String
with type
t0 t1
while checking that type String
is at least as general as type t0 t1
while checking that expression key ke
has type t0 t1
in value declaration test
where t0 is an unknown type
t1 is an unknown type
See https://github.com/purescript/documentation/blob/master/errors/TypesDoNotUnify.md for more information,
or to contribute content related to this error.
* ERROR: Subcommand terminated with exit code 1
您的 test
函数需要稍微调整一下:
import Prelude
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Class (liftEff)
import Control.Monad.Eff.Console (CONSOLE, log)
import Control.Monad.Except (runExcept)
import DOM (DOM)
import DOM.Event.Event (Event)
import DOM.Event.EventTarget (addEventListener, eventListener)
import DOM.Event.KeyboardEvent as KE
import DOM.Event.Types (EventType(..))
import DOM.HTML (window)
import DOM.HTML.Types as DHT
import DOM.HTML.Window (document)
import Data.Either (Either(..))
test :: forall e. Event -> Eff ( console :: CONSOLE, dom :: DOM | e) Unit
test a =
case runExcept (KE.eventToKeyboardEvent a) of
Left err ->
log "Event was not a keyboard event"
Right ke -> do
let co = KE.key ke
log "Key Pressed : "
main :: forall e. Eff (console :: CONSOLE, dom :: DOM | e) Unit
main = do
documenttarget <- liftEff $ window >>= document <#> DHT.htmlDocumentToEventTarget
addEventListener (EventType "keydown") (eventListener test) true (documenttarget)
首先,KE.key
和 KE.eventToKeyboardEvent
不是有效函数,这意味着您无需绑定即可从中获取值(这就是 t0 t1
错误的原因关于:对于某些 m
).
m String
而不仅仅是 String
接下来,当我们使用 eventToKeyboardEvent
时,它可能会失败,因为我们无法保证将任何 Event
强制转换为 KeyboardEvent
是安全的。结果包含在 F
, which is a synonym for Except MultipleErrors
中,所以我们需要做一些事情来获得结果。我们 "run" Except
包装器返回 Either
,其中 Left
端是错误消息,Right
是成功结果。
在这个例子中,我在转换失败时记录了它,但你可能不关心这个,通常甚至不希望这种情况被命中,在这种情况下使用 pure unit
是可能已经足够好了。
如果您愿意让失败案例什么都不做,实际上还有另一种写法:
import Data.Foldable (for_)
test :: forall e. Event -> Eff ( console :: CONSOLE, dom :: DOM | e) Unit
test a =
for_ (runExcept (KE.eventToKeyboardEvent a)) \ke -> do
let co = KE.key ke
log "Key Pressed : "
for_
实际上是一个高度通用的函数,可以用于各种各样的东西,但是这种使用它来静静地吸收失败的方法在编写代码以对抗丑陋的东西时非常方便 DOM API.