gpt4 book ai didi

javascript - 从 EventM 中删除当前监听器

转载 作者:行者123 更新时间:2023-11-28 17:36:17 25 4
gpt4 key购买 nike

假设我想使用 ghcjs-dom 创建一个事件监听器,该事件监听器响应单击,然后自行删除。

我有

addListener :: (IsEventTarget t, IsEvent e)
=> t -> EventName t e -> SaferEventListener t e -> Bool -> IO ()
removeListener :: (IsEventTarget t, IsEvent e)
=> t -> EventName t e -> SaferEventListener t e -> Bool -> IO ()

添加和删除,以及

newListener :: (IsEvent e) => EventM t e () -> IO (SaferEventListener t e)

EventM 构造监听器。如何从 EventM 中访问 SaferEventListener(我稍后将构造),以便在事件发生时将其删除?

在 JavaScript 中,您可以使用命名函数表达式作为对 addEventListener 的回调,然后在回调中将 removeEventListener 应用于该名称。但这里似乎没有类似的事情是可能的。或者我错过了什么?

最佳答案

使用fixIO

fixIO $ \rec -> newListener _eventm

用您的 EventM 填充 _eventm,您将能够访问最终通过名称 rec 创建的事件监听器。 rec 将是 newListener 调用的结果,但可以在执行之前“使用”它。我说“使用过”,因为尝试使用 seq 或任何更强的东西强制它会导致无限循环,但你应该可以很好地做你正在做的事情。

<小时/>

fixIOfix 的泛化:

-- the essence of recursion
fix :: (a -> a) -> a
fix f = let x = f x in x
-- equivalent but less performant and less relevant
fix f = f (fix f)

-- if you have used JS's "named anonymous functions"
-- this will seem very familiar
(fix (\fact n ->
if n <= 1 then 1 else n * fact (n - 1)
)) 3 = 6
-- JS:
-- (function fact(n) {
-- if(n <= 1) { return 1; } else { return n * fact(n - 1); }
-- })(3) === 6

-- but this has more power
repeat = fix . (:)
repeat 1 = fix (1:) =
let x = 1:x in x = 1:fix (1:) = [1,1,1,1,1,1,1,1,1,1,1,1,1,1...]

fix id = let x = id x in x = let x = x in x = _|_ -- oops!

fixIO :: (a -> IO a) -> IO a
fixIO f = _ -- horrendous, unsafe code

fixIO (\xs -> return $ 1:xs) = return [1,1,1,1,1,1,1,1,1,1...]

fixIO return = fixIO (return . id) = return $ fix id = return _|_ -- oops!

fix 的想法是在函数实际创建之前使其最终结果可用。
fixIO 的想法是在实际创建 IO 函数之前使其可以使用它的最终结果,同时还执行一些 IO 操作。此外,fixIO 仅执行这些操作一次,这就是为什么 fix 的第一个定义(仅调用 f) > 一次)比第二次更相关。

fixIO 又是 mfix::MonadFix m => (a -> m a) -> m a 的特化,其中 MonadFix code> 是承认这种打结语义的 monad 类(包括 IO,带有 mfix = fixIO)。 GHC 支持任何 MonadFix 的“递归 do”表示法:

{-# LANGUAGE RecursiveDo #-}
someCode = mdo ...
listener <- newListener _eventm -- can access listener in definition
...
-- or
someCode = do ...
rec listener <- newListener _eventm
...

关于javascript - 从 EventM 中删除当前监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49077219/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com