Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
316 views
in Technique[技术] by (71.8m points)

javascript - 从EventM中删除当前的侦听器(removing the current listener from within EventM)

Suppose I want to create, using ghcjs-dom, an event listener which responds to a click, and then removes itself.(假设我想使用ghcjs-dom创建一个事件侦听器,该事件侦听器对单击做出响应,然后将其自身删除。)

I have(我有) 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 () to add and remove, and(添加和删??除,以及) newListener :: (IsEvent e) => EventM t e () -> IO (SaferEventListener t e) to construct the listener out of an EventM .(从EventM构造侦听EventM 。) How can I access the SaferEventListener (which I will only later construct) from within the EventM , in order to remove it when the event occurs?(我怎样才能访问SaferEventListener从(我将只是后来建造)的内EventM ,以便在事件发生时将其删除?) In JavaScript, you use a named function expression as your callback to addEventListener , and then apply removeEventListener to that name from within the callback.(在JavaScript中,您可以使用命名函数表达式作为addEventListener的回调,然后在回调中将removeEventListener应用于该名称。) But nothing analogus seems to be possible here.(但是,这里似乎没有任何类比。) Or am I missing something?(还是我错过了什么?)   ask by Graham Leach-Krouse translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Use fixIO(使用fixIO)

fixIO $ ec -> newListener _eventm Fill _eventm with your EventM , and you will be able to access the event listener that will eventually be created through the name rec .(用EventM填充_eventm ,您将能够访问最终通过名称rec创建的事件侦听器。) rec will be the result of the newListener call, but it can be "used" before that is executed.(rec将是newListener调用的结果,但在执行之前可以被“使用”。) I say "used," because trying to force it with seq or anything stronger will cause an infinite loop, but you should be fine doing what you're doing.(我说“二手”是因为尝试用seq或任何更强的力强制它会导致无限循环,但是您在做自己的工作时应该没事。) fixIO is a generalization of fix :(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! The idea of fix is making a function's eventual result available to it before it is actually created.(fix的想法是在实际创建函数之前使函数的最终结果可用。)
The idea of fixIO is making an IO function's eventual result available to it before it is actually created while also carrying out some IO actions .(fixIO的想法是在实际创建IO函数之前将其最终结果提供给它, 同时还要执行一些IO操作 。) Also, fixIO only carries out these actions once , which is why the first definition of fix (that only calls f once) is more relevant than the second.(同样, fixIO只执行一次这些操作,这就是为什么fix的第一个定义(仅调用f一次)比第二个更相关的原因。) fixIO , in turn, is a specialization of mfix :: MonadFix m => (a -> ma) -> ma , where MonadFix is the class of monads (including IO , with mfix = fixIO ) that admit such knot-tying semantics.(fixIO反过来是mfix :: MonadFix m => (a -> ma) -> ma ,其中MonadFix是接受此类打结语义的monads的类(包括IO ,其中mfix = fixIO )。) GHC supports "recursive do " notation for any MonadFix :(GHC支持任何MonadFix “递归do ”符号:) {-# LANGUAGE RecursiveDo #-} someCode = mdo ... listener <- newListener _eventm -- can access listener in definition ... -- or someCode = do ... rec listener <- newListener _eventm ...

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...