本文介绍了反应 - 香蕉节流事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我想在反应式香蕉中实施某种类型的事件限制。它应该起作用,以使得如果从最后一次通过的事件到达的时间少于三秒,事件就不会通过。如果它没有通过,那么它将被存储并在最后一次触发事件的增量秒后触发。 下面是一个程序,用于实现这个时间戳数字列表。这是否有可能将其转化为反应性香蕉? 另外,在反应性香蕉中,在其他事件进入后x秒钟内如何发生事件? p> 模块Main其中 导入Data.List - 1秒throtling - 逻辑在输出最后一个值之后的1秒之前从不输出一个值。 main :: IO() main = print $ test [(0.0,1.0),(1.1,2.0),(1.5,3.0),(1.7,4.0),(2.2) ,5.0)] - 应该输出[(0.0,1.0),(1.1,2.0),(2.1,4.0),(3.1,5.0)] test :: [( Double,Double)] - > [(Double,Double)] test list = gv(concat xs)其中(v,xs)= mapAccumL f(-50,Nothing)list g(t,Just x)ys = ys ++ [(t + 1,x)] g _ ys = ys f(lasttime,Just holdvalue)(t,x)= if t >(lasttime + 1)then if t>(lasttime + 2)then ((t,Nothing),[(lasttime + 1,holdvalue),(t,x)]) else((lasttime + 1,Just x),[(lasttime + 1,holdvalue)]) else ((lasttime,Just x),[])f(lasttime,Nothing )(t,x)= if t>(lasttime + 1)then ((t,Nothing) ,[(t,x)]) else((lasttime,Just x),[]) 解决方案好的,我设法实现了我在我的问题中描述的内容。我不是很高兴IO需要通过反应来控制计时器。我不知道是否可以用节气门标记油门:: Event ta - > Int - > Event ta ... ps:我很新手在Haskell中,所以代码可能会更紧凑或优雅。 {----------- -------------------------------------------------- ---------------- -------------------------- -------------------------------------------------- - } { - #LANGUAGE ScopedTypeVariables# - } - 允许forall t。NetworkDescription t import Graphics.UI.WX隐藏(事件)导入无效。 Banana import Reactive.Banana.WX import Data.Time {---------------------- -------------------------------------------------- ----- 主 ------------------------------------ ------------------------------------------} 数据ThrottledValue a = FireStoredValue a | FireNowAndStartTimer a | HoldIt a |停止导出显示数据ThrottledEvent a = TimerEvent | RealEvent派生Show main = start $ do f< - frame [text:=Countercesss] sl1< - hslider f False 0 100 [] sl2 set f [layout:= column 0 [widget sl1,widget sl2]] t set t [enabled:= False] 让networkDescription :: forall t。 NetworkDescription t() networkDescription = do slEv< - event0 sl1命令 tick< - event0 t命令 slB< - 行为sl1选择 let throttledEv,reactimates)= throttle(slB reactimates reactimates $ fmap(\ x - > set sl2 [selection:= x])throttledEv net < - 编译网络描述启动网络 throttle :: Event ta - >事件t() - >定时器 - > Int - > (事件ta,NetworkDescription t()) throttle ev tick timer dt =(throttledEv,reactimates)其中 all = union(fmap(\ x-> RealEvent x)ev) (fmap(\ x - > TimerEvent)tick) result = accumE已停止$ fmap h全部其中h(RealEvent x)Stopped = FireNowAndStartTimer x h TimerEvent Stopped = Stopped h(RealEvent x)(FireEowAndStartTimer _)= HoldIt x h TimerEvent(FireNowAndStartTimer _)=已停止h(RealEvent x)(HoldIt _)= HoldIt x h(TimerEvent) y)= FireStoredValue y h(RealEvent x)(FireStoredValue _)= HoldIt x h(TimerEvent)(FireStoredValue _)= Stopped start(FireStoredValue a)= Just $ resetTimer timer dt start(FireNowAndStartTimer a)= Just $ resetTimer timer dt start _ = Nothing stop Stopped = Just $ stopTimer timer stop _ = Nothing reactimates = do reactimate $ filterJust $ fmap停止结果 reactimate $ filterJust $ fmap开始结果 filterFired(FireStoredValue a)=只需 filterFired(FireNowAndStartTimer a)=只需 filterFired _ = Nothing throttledEv = filterJust $ fmap filterFired result $ b startTimer t dt = set t [enabled:= True,interval:= dt] stopTimer t = set t [enabled := False] resetTimer t dt = stopTimer t>> startTimer t dt I would like to implement a certain type of throttling of events in reactive-banana. It should work such that an event is not let through if arrives at less then delta seconds from the last event that passed through. If it is not let through then it is stored and is fired after delta seconds from the last fired event.Below is a program that implements this for lists of time stamped numbers. Would it be possible to translate this to reactive-banana ?Also, in reactive-banana how do I fire an event x seconds after some other event comes in ?module Main whereimport Data.List-- 1 second throtling-- logic is to never output a value before 1 second has passed since last value was outputed.main :: IO()main = print $ test [ (0.0, 1.0), (1.1, 2.0), (1.5,3.0), (1.7,4.0), (2.2, 5.0) ]--should output [ (0.0, 1.0), (1.1, 2.0), (2.1,4.0), (3.1, 5.0) ]test :: [(Double,Double)] -> [(Double,Double)]test list = g v (concat xs) where (v, xs) = mapAccumL f (-50,Nothing) list g (t, Just x) ys = ys ++ [ (t+1,x) ] g _ ys = ys f (lasttime, Just holdvalue) (t,x) = if t > (lasttime+1) then if t > (lasttime + 2) then ( (t, Nothing), [ (lasttime+1,holdvalue), (t,x)] ) else ( (lasttime+1, Just x) , [ (lasttime+1,holdvalue) ] ) else ( (lasttime, Just x), [] ) f (lasttime, Nothing) (t,x) = if t > (lasttime+1) then ( (t,Nothing) , [ (t, x ) ] ) else ( (lasttime, Just x), [] ) 解决方案 Ok, I managed to implement what I described in my question. I'm not so happy that IO is needed to control the timer via reactimate. I wonder if it would be possible to have a throttle with signature throttle::Event t a -> Int -> Event t a ...ps: I'm very novice in Haskell so the code could probably a lot more compact or elegant.{-----------------------------------------------------------------------------------------------------------------------------------------------------------}{-# LANGUAGE ScopedTypeVariables #-} -- allows "forall t. NetworkDescription t"import Graphics.UI.WX hiding (Event)import Reactive.Bananaimport Reactive.Banana.WXimport Data.Time{----------------------------------------------------------------------------- Main------------------------------------------------------------------------------}data ThrottledValue a = FireStoredValue a | FireNowAndStartTimer a| HoldIt a | Stopped deriving Showdata ThrottledEvent a = TimerEvent | RealEvent a deriving Showmain = start $ do f <- frame [text := "Countercesss"] sl1 <- hslider f False 0 100 [] sl2 <- hslider f False 0 100 [] set f [ layout := column 0 [widget sl1, widget sl2] ] t <- timer f [] set t [ enabled := False ] let networkDescription :: forall t. NetworkDescription t () networkDescription = do slEv <- event0 sl1 command tick <- event0 t command slB <- behavior sl1 selection let (throttledEv, reactimates) = throttle (slB <@ slEv) tick t 100 reactimates reactimate $ fmap (\x -> set sl2 [selection := x]) throttledEv net <- compile networkDescription actuate netthrottle::Event t a -> Event t () -> Timer -> Int -> (Event t a, NetworkDescription t () )throttle ev tick timer dt = (throttledEv, reactimates) where all = union (fmap (\x-> RealEvent x) ev) (fmap (\x -> TimerEvent) tick) result = accumE Stopped $ fmap h all where h (RealEvent x) Stopped = FireNowAndStartTimer x h TimerEvent Stopped = Stopped h (RealEvent x) (FireNowAndStartTimer _) = HoldIt x h TimerEvent (FireNowAndStartTimer _) = Stopped h (RealEvent x) (HoldIt _) = HoldIt x h (TimerEvent) (HoldIt y) = FireStoredValue y h (RealEvent x) (FireStoredValue _) = HoldIt x h (TimerEvent) (FireStoredValue _) = Stopped start (FireStoredValue a) = Just $ resetTimer timer dt start (FireNowAndStartTimer a) = Just $ resetTimer timer dt start _ = Nothing stop Stopped = Just $ stopTimer timer stop _ = Nothing reactimates = do reactimate $ filterJust $ fmap stop result reactimate $ filterJust $ fmap start result filterFired (FireStoredValue a) = Just a filterFired (FireNowAndStartTimer a) = Just a filterFired _ = Nothing throttledEv = filterJust $ fmap filterFired resultstartTimer t dt = set t [ enabled := True, interval := dt ]stopTimer t = set t [ enabled := False ]resetTimer t dt = stopTimer t >> startTimer t dt 这篇关于反应 - 香蕉节流事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
09-14 09:05