- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 PureScript 制作 Canvas 游戏,我想知道处理事件监听器的最佳方法是什么,特别是在自定义 monad 堆栈中运行回调。这是我的游戏堆栈...
type BaseEffect e = Eff (canvas :: CANVAS, dom :: DOM, console :: CONSOLE | e)
type GameState = { canvas :: CanvasElement, context :: Context2D, angle :: Number }
type GameEffect e a = StateT GameState (BaseEffect e) a
我想做的是在按下任意键时更改 GameState 中的“角度”属性(仅出于开发目的,以便我可以调整图形)。这是我的回调函数...
changeState :: forall e. Event -> GameEffect e Unit
changeState a = do
modify \s -> s { angle = s.angle + 1.0 }
liftEff $ log "keypress"
pure unit
但是 addEventListener和 eventListener看起来它们只能与 Eff 一起使用,因此以下内容不会键入检查...
addEventListener
(EventType "keypress")
(eventListener changeState)
false
((elementToEventTarget <<< htmlElementToElement) bodyHtmlElement)
我想我可以自己定义 addEventListener 和 eventListener使用外部函数接口(interface)导入它们(将 Eff 更改为 GameEffect)。该类型已检查,但当我尝试在浏览器中运行时导致控制台错误。
foreign import addEventListener :: forall e. EventType -> EventListener e -> Boolean -> EventTarget -> GameEffect e Unit
foreign import eventListener :: forall e. (Event -> GameEffect e Unit) -> EventListener e
处理 monad 堆栈中正在运行的回调的最佳方法是什么?
最佳答案
我会使用purescript-aff-coroutines
为了这。这意味着将 BaseEffect
更改为 Aff
,但任何 Eff
能做的事情 Aff
也能做:
import Prelude
import Control.Coroutine as CR
import Control.Coroutine.Aff as CRA
import Control.Monad.Aff (Aff)
import Control.Monad.Aff.AVar (AVAR)
import Control.Monad.Eff.Class (liftEff)
import Control.Monad.Eff.Console (CONSOLE, log)
import Control.Monad.Rec.Class (forever)
import Control.Monad.State (StateT, lift, modify)
import Data.Either (Either(..))
import DOM (DOM)
import DOM.Event.EventTarget (addEventListener, eventListener)
import DOM.Event.Types (Event, EventTarget, EventType(..))
import DOM.HTML.Types (HTMLElement, htmlElementToElement)
import DOM.Node.Types (elementToEventTarget)
import Graphics.Canvas (CANVAS, CanvasElement, Context2D)
type BaseEffect e = Aff (canvas :: CANVAS, dom :: DOM, console :: CONSOLE, avar :: AVAR | e)
type GameState = { canvas :: CanvasElement, context :: Context2D, angle :: Number }
type GameEffect e = StateT GameState (BaseEffect e)
changeState :: forall e. Event -> GameEffect e Unit
changeState a = do
modify \s -> s { angle = s.angle + 1.0 }
liftEff $ log "keypress"
pure unit
eventProducer :: forall e. EventType -> EventTarget -> CR.Producer Event (GameEffect e) Unit
eventProducer eventType target =
CRA.produce' \emit ->
addEventListener eventType (eventListener (emit <<< Left)) false target
setupListener :: forall e. HTMLElement -> GameEffect e Unit
setupListener bodyHtmlElement = CR.runProcess $ consumer `CR.pullFrom` producer
where
producer :: CR.Producer Event (GameEffect e) Unit
producer =
eventProducer
(EventType "keypress")
((elementToEventTarget <<< htmlElementToElement) bodyHtmlElement)
consumer :: CR.Consumer Event (GameEffect e) Unit
consumer = forever $ lift <<< changeState =<< CR.await
因此,这里的 eventProducer
函数为事件监听器创建一个协程生成器,然后 setupListener
执行与理论上的 addEventListener
等效的操作你上面的用法。
其工作原理是为监听器创建一个生产者,然后将其连接到接收到 Event
时调用 changeState
的消费者。协程进程在单子(monad)上下文中运行,这里是您的 GameEffect
单子(monad),这就是一切顺利的原因。
关于dom - (PureScript) 如何在 Eff 以外的单子(monad)上下文中运行 DOM 事件监听器回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42080807/
阅读 Eff-Language 时,我想知道是否有类似的想法已经在使用。 Eff-Language 提到了一篇名为“Inferring Algebraic Effects”的论文,它描述了 Eff 用
Purescript 类型之间有什么关系 Eff 和 Aff ?可以在它们之间转换吗? 我刚开始使用来自 Haskell 的 Purescript,似乎这两种类型都大致扮演了 IO 的角色。在 Has
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我正在使用 purescript-node-http 学习 Purescript图书馆。如果我有一个值,其类型如下: > :t f forall t3. Eff ( http :: HTT
我想尽可能地限制程序中函数的影响,以便例如如果我有一个应该查询数据库的函数,我知道它不会打印用于删除我的文件的内容。 作为一个具体示例,假设我有一个带有“用户”表的数据库。 有些函数只能读取该表,有些
Eff monad 看起来比 monad 转换器好得多,也更有用,并且可以用 monad 转换替换样板,但是 Free monad 可以通过提供之间的划分来实现完全相同的事情执行和程序定义,因此 Ef
我试图理解为什么以下内容在 Purescript 中不起作用。我感觉 Haskell 社区也可以回答这个问题,因此我将其交叉列出。 总体要点是: 如果我有一个 do block ,我可以不添加一次性值
我想做一些需要效果的编程(谁不需要:-)。 特别是像 scalaz Task 运行一些异步数据检索和 ruturn 类似 Future 的效果,它将在完成时处理结果。 我注意到类型级别的 Cats 现
我正在将 History.js 中的绑定(bind)编写到 PureScript 中,但仍在努力理解 Eff monad、一排效果是什么以及它们为何有值(value)。现在我用 EasyFFI 写了以
我正在使用 PureScript 制作 Canvas 游戏,我想知道处理事件监听器的最佳方法是什么,特别是在自定义 monad 堆栈中运行回调。这是我的游戏堆栈... type BaseEffect
在monad transformers , 我们有 instance (Monad m, Monoid e) => MonadPlus (ExceptT e m) 在extensible effect
我正在尝试通过套接字发送 29 位 EFF CAN 消息,但由于某种原因,它使用 11 位标识符发送消息,从 ID 中删除 5 个字节。使用环回模式,通过 candump 我可以看到消息以 11 位形
我是一名优秀的程序员,十分优秀!