summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuhaPaananen <>2012-05-09 20:22:02 (GMT)
committerhdiff <hdiff@luite.com>2012-05-09 20:22:02 (GMT)
commit1a0160d8e86932c0a50eafc74e6b0d18ea1508bf (patch)
treece462f0d88f474e8c1d9916d00de758937e505e0
parent2b3ac9e6298dd353eb4f9f453ca4c8b81111a996 (diff)
version 0.40.4
-rw-r--r--reactive-bacon.cabal3
-rw-r--r--src/Reactive/Bacon/EventStream.hs11
-rw-r--r--src/Reactive/Bacon/EventStream/Monadic.hs10
-rw-r--r--src/Reactive/Bacon/EventStream/Timed.hs2
4 files changed, 19 insertions, 7 deletions
diff --git a/reactive-bacon.cabal b/reactive-bacon.cabal
index 559f8f1..8bfb7be 100644
--- a/reactive-bacon.cabal
+++ b/reactive-bacon.cabal
@@ -1,5 +1,5 @@
Name: reactive-bacon
-Version: 0.3
+Version: 0.4
Stability: experimental
Synopsis: FRP (functional reactive programming) framework
Description: FRP (functional reactive programming) framework inspired by RX, reactive-banana and Iteratee
@@ -38,6 +38,7 @@ Test-Suite tests
Build-depends:
base >= 4 && < 5,
old-time >= 1.0.0.6,
+ stm >= 2.2.0.1,
HUnit >= 1.2.2.3,
containers >= 0.4.0.0
ghc-options: -threaded
diff --git a/src/Reactive/Bacon/EventStream.hs b/src/Reactive/Bacon/EventStream.hs
index 3ecac72..d8e9455 100644
--- a/src/Reactive/Bacon/EventStream.hs
+++ b/src/Reactive/Bacon/EventStream.hs
@@ -34,6 +34,17 @@ filterE f = return . sinkMap filteredSink
filteredSink sink (Next x) | f x = sink (Next x)
| otherwise = return More
+
+skipDuplicatesE :: EventSource s => Eq a => s a -> IO (EventStream a)
+skipDuplicatesE = scanE withEquality (Nothing, False) >=> filterE snd >=> mapE (fromJust . fst)
+ where withEquality (Nothing, _) x = (Just x, True)
+ withEquality (Just y, _) x | x == y = (Just x, False)
+ | otherwise = (Just x, True)
+
+stateMachineE :: EventSource s => (st -> a -> (st, b)) -> st -> s a -> IO (EventStream b)
+stateMachineE f startState = scanE scanF (startState, Nothing) >=> mapE (fromJust . snd)
+ where scanF (state, _) x = (fst $ f state x, Just $ snd $ f state x)
+
takeWhileE :: EventSource s => (a -> Bool) -> s a -> IO (EventStream a)
takeWhileE f src = do stopFlag <- newIORef False
wrap $ sinkMap (guardedSink stopFlag) src
diff --git a/src/Reactive/Bacon/EventStream/Monadic.hs b/src/Reactive/Bacon/EventStream/Monadic.hs
index 958d35b..cec6598 100644
--- a/src/Reactive/Bacon/EventStream/Monadic.hs
+++ b/src/Reactive/Bacon/EventStream/Monadic.hs
@@ -1,4 +1,4 @@
-module Reactive.Bacon.EventStream.Monadic(selectManyE, switchE) where
+module Reactive.Bacon.EventStream.Monadic(flatMapE, switchE) where
import Data.IORef
import Reactive.Bacon.Core
@@ -9,10 +9,10 @@ import Control.Concurrent.STM
import Control.Monad
-- EventStream is not a Monad
--- However, selectManyE and switchE have a signature that's pretty close
+-- However, flatMapE and switchE have a signature that's pretty close
-- to monadic bind. The difference is that IO is allowed in the bind step.
-selectManyE :: EventSource s => (a -> IO (EventStream b)) -> s a -> IO (EventStream b)
-selectManyE binder xs = wrap $ EventStream $ \sink -> do
+flatMapE :: EventSource s => (a -> IO (EventStream b)) -> s a -> IO (EventStream b)
+flatMapE binder xs = wrap $ EventStream $ \sink -> do
state <- newTVarIO $ State sink Nothing 1 [] [] False
dispose <- subscribe (obs xs) $ mainEventSink state
atomically $ modifyTVar state $ \state -> state { dispose = Just dispose }
@@ -60,7 +60,7 @@ selectManyE binder xs = wrap $ EventStream $ \sink -> do
withState state action = atomically (readTVar state >>= action)
switchE :: EventSource s => (a -> IO (EventStream b)) -> s a -> IO (EventStream b)
-switchE binder src = selectManyE (binder >=> (takeUntilE src)) src
+switchE binder src = flatMapE (binder >=> (takeUntilE src)) src
data State a = State { currentSink :: EventSink a,
dispose :: Maybe Disposable,
diff --git a/src/Reactive/Bacon/EventStream/Timed.hs b/src/Reactive/Bacon/EventStream/Timed.hs
index b1935db..ad8ca53 100644
--- a/src/Reactive/Bacon/EventStream/Timed.hs
+++ b/src/Reactive/Bacon/EventStream/Timed.hs
@@ -29,7 +29,7 @@ timedE events = fromStoppableProcess $ \sink stopper -> void $ forkIO $ serve si
serve sink events getStopState
delayE :: EventSource s => TimeDiff -> s a -> IO (EventStream a)
-delayE diff = selectManyE (laterE diff)
+delayE diff = flatMapE (laterE diff)
throttleE :: EventSource s => TimeDiff -> s a -> IO (EventStream a)
throttleE diff = switchE (laterE diff)