2012-04-03 8 views
7

En reactive-banana tengo un flujo de eventos que produce una serie de números, algunos de los cuales se repiten varias veces seguidas (no me preocupan todos los duplicados, solo duplicados secuenciales). ¿Cómo puedo modificar esa secuencia de eventos para que contenga solo duplicados no secuenciales?Cómo eliminar eventos repetitivos en reactive-banana

Traté de usar cambios para convertirlo en un comportamiento pensando que el comportamiento solo "cambiaría" cuando el evento era un número nuevo, pero el comportamiento desencadena un evento de cambio cada vez que se recibe un nuevo evento de entrada.

Respuesta

6

Tenga en cuenta que la función debe changes solamente ser utilizado para la unión a herramientas GUI y thelike, debe no se utiliza para la programación regular con eventos y comportamientos.

Una función que suprime ocurrencias de eventos duplicados se puede expresar en términos de las mapAccum y filterJust combinadores como sigue

skipEqual :: Eq a => Event t a -> Event t a 
skipEqual = filterJust . fst . mapAccum Nothing . fmap f 
    where 
    f y (Just x) = if x == y then (Nothing,Just x) else (Just y,Just y) 
    f y Nothing = (Just y, Just y) 

test = interpretModel skipEqual $ map (:[]) [1 :: Int,1,2,3,3,2] 

Correr test da

*Main> test 
[[1],[],[2],[3],[],[2]] 

como deseado.

En otras palabras, puede simplemente imaginar Event como una lista de las ocurrencias y luego aplicar sus amados "listas" combinadores a eso.

+0

Oh, ¿por qué no pensé en eso? He eliminado la implementación fea de mi respuesta a favor de esta. – ehird

+1

si no debe usar cambios, ¿cómo hace algo significativo con un comportamiento? – Orclev

+0

@Orclev: puede 'aplicar' comportamientos a eventos. Los operadores '<@>' y '<@' se usan para eso. Además, puede usar la recursión mutua entre comportamientos y eventos. –

0

Bueno, changes no convierte nada en un Behavior; simplemente deja que observe los cambios de Behavior en NetworkDescription, para que pueda pegarlo en marcos externos. El behaviour of changes se describe como changes (stepper x e)return (calm e), por lo que el disparo circular de un evento a través de stepper y changes no tendrá ningún efecto más que calm (que simplemente descarta todas las apariciones simultáneas excepto la primera).

Es útil tener un combinador para descartar eventos que no cambien el valor, y creo que algunos otros marcos de FRP tienen uno incorporado. Pero puede escribir el suyo con bastante facilidad, como lo muestra la respuesta de Heinrich.

Cuestiones relacionadas