elerea 2.6.0 → 2.7.0
raw patch · 6 files changed
+155/−26 lines, 6 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ FRP.Elerea.Simple.Pure: delay :: a -> Signal a -> SignalGen (Signal a)
+ FRP.Elerea.Simple.Pure: fromList :: [a] -> Signal a
+ FRP.Elerea.Simple.Pure: generator :: Signal (SignalGen a) -> SignalGen (Signal a)
+ FRP.Elerea.Simple.Pure: memo :: Signal a -> SignalGen (Signal a)
+ FRP.Elerea.Simple.Pure: snapshot :: Signal a -> SignalGen a
+ FRP.Elerea.Simple.Pure: start :: SignalGen (Signal a) -> [a]
+ FRP.Elerea.Simple.Pure: stateful :: a -> (a -> a) -> SignalGen (Signal a)
+ FRP.Elerea.Simple.Pure: toList :: Signal a -> [a]
+ FRP.Elerea.Simple.Pure: transfer :: a -> (t -> a -> a) -> Signal t -> SignalGen (Signal a)
+ FRP.Elerea.Simple.Pure: transfer2 :: a -> (t1 -> t2 -> a -> a) -> Signal t1 -> Signal t2 -> SignalGen (Signal a)
+ FRP.Elerea.Simple.Pure: transfer3 :: a -> (t1 -> t2 -> t3 -> a -> a) -> Signal t1 -> Signal t2 -> Signal t3 -> SignalGen (Signal a)
+ FRP.Elerea.Simple.Pure: transfer4 :: a -> (t1 -> t2 -> t3 -> t4 -> a -> a) -> Signal t1 -> Signal t2 -> Signal t3 -> Signal t4 -> SignalGen (Signal a)
+ FRP.Elerea.Simple.Pure: type Signal a = Int -> a
+ FRP.Elerea.Simple.Pure: type SignalGen a = Int -> a
+ FRP.Elerea.Simple.Pure: until :: (a -> Bool) -> (a -> a) -> a -> a
Files
- CHANGES +5/−0
- FRP/Elerea/Clocked.hs +16/−4
- FRP/Elerea/Param.hs +17/−5
- FRP/Elerea/Simple.hs +28/−16
- FRP/Elerea/Simple/Pure.hs +85/−0
- elerea.cabal +4/−1
CHANGES view
@@ -1,3 +1,8 @@+2.7.0 - 111223+* fixed an issue with nested signal creations not updating properly+ (courtesy of Takano Akio)+* added reference implementation for the simple variant+ 2.6.0 - 111211 * added snapshot to all variants, which allows sampling signals within signal generators
FRP/Elerea/Clocked.hs view
@@ -208,11 +208,23 @@ S sample <- gen pool pool return $ do res <- sample- (ptrs,acts) <- unzip.catMaybes <$> (mapM getUpdate =<< readIORef pool)- writeIORef pool ptrs- mapM_ fst acts- mapM_ snd acts+ superstep pool return res++-- | Performing the two-phase superstep.+superstep :: IORef UpdatePool -> IO ()+superstep pool = loop id []+ where+ loop getPtrs final = do+ (ptrs,acts) <- unzip.catMaybes <$> (mapM getUpdate =<< readIORef pool)+ case acts of+ [] -> do+ sequence_ final+ writeIORef pool (getPtrs [])+ _ -> do+ writeIORef pool []+ mapM_ fst acts+ loop ((ptrs++) . getPtrs) (mapM_ snd acts : final) -- | Auxiliary function used by all the primitives that create a -- mutable variable.
FRP/Elerea/Param.hs view
@@ -145,14 +145,26 @@ (inp,sink) <- external undefined S sample <- gen pool inp return $ \param -> do- let deref ptr = (fmap.fmap) ((,) ptr) (deRefWeak ptr) sink param res <- sample- (ptrs,acts) <- unzip.catMaybes <$> (mapM deref =<< readIORef pool)- writeIORef pool ptrs- mapM_ fst acts- mapM_ snd acts+ superstep pool return res++-- | Performing the two-phase superstep.+superstep :: IORef UpdatePool -> IO ()+superstep pool = loop id []+ where+ deref ptr = (fmap.fmap) ((,) ptr) (deRefWeak ptr)+ loop getPtrs final = do+ (ptrs,acts) <- unzip.catMaybes <$> (mapM deref =<< readIORef pool)+ case acts of+ [] -> do+ sequence_ final+ writeIORef pool (getPtrs [])+ _ -> do+ writeIORef pool []+ mapM_ fst acts+ loop ((ptrs++) . getPtrs) (mapM_ snd acts : final) -- | Auxiliary function used by all the primitives that create a -- mutable variable.
FRP/Elerea/Simple.hs view
@@ -99,18 +99,18 @@ data Phase a = Ready a | Updated a a instance Functor SignalGen where- fmap = liftM+ fmap = liftM instance Applicative SignalGen where- pure = return- (<*>) = ap+ pure = return+ (<*>) = ap instance Monad SignalGen where- return x = SG $ \_ -> return x- SG g >>= f = SG $ \p -> g p >>= \x -> unSG (f x) p+ return x = SG $ \_ -> return x+ SG g >>= f = SG $ \p -> g p >>= \x -> unSG (f x) p instance MonadFix SignalGen where- mfix f = SG $ \p -> mfix $ \x -> unSG (f x) p+ mfix f = SG $ \p -> mfix $ \x -> unSG (f x) p -- | Embedding a signal into an 'IO' environment. Repeated calls to -- the computation returned cause the whole network to be updated, and@@ -134,16 +134,28 @@ start :: SignalGen (Signal a) -- ^ the generator of the top-level signal -> IO (IO a) -- ^ the computation to sample the signal start (SG gen) = do- pool <- newIORef []- S sample <- gen pool- return $ do- let deref ptr = (fmap.fmap) ((,) ptr) (deRefWeak ptr)- res <- sample- (ptrs,acts) <- unzip.catMaybes <$> (mapM deref =<< readIORef pool)- writeIORef pool ptrs- mapM_ fst acts- mapM_ snd acts- return res+ pool <- newIORef []+ S sample <- gen pool+ return $ do+ res <- sample+ superstep pool+ return res++-- | Performing the two-phase superstep.+superstep :: IORef UpdatePool -> IO ()+superstep pool = loop id []+ where+ deref ptr = (fmap.fmap) ((,) ptr) (deRefWeak ptr)+ loop getPtrs final = do+ (ptrs,acts) <- unzip.catMaybes <$> (mapM deref =<< readIORef pool)+ case acts of+ [] -> do+ sequence_ final+ writeIORef pool (getPtrs [])+ _ -> do+ writeIORef pool []+ mapM_ fst acts+ loop ((ptrs++) . getPtrs) (mapM_ snd acts : final) -- | Auxiliary function used by all the primitives that create a -- mutable variable.
+ FRP/Elerea/Simple/Pure.hs view
@@ -0,0 +1,85 @@+{-|++This module contains the reference implementation for the pure subset+of the simple variant of Elerea. I/O embedding is substituted by+conversion from and to lists.++-}++module FRP.Elerea.Simple.Pure+ (+ -- * The signal abstraction+ Signal+ , SignalGen+ -- * Inputs and outputs+ , fromList+ , toList+ , start+ -- * Basic building blocks+ , delay+ , snapshot+ , generator+ , memo+ , until+ -- * Derived combinators+ , stateful+ , transfer+ , transfer2+ , transfer3+ , transfer4+ ) where++import Control.Applicative+import Control.Monad+import Control.Monad.Fix++type Signal a = Int -> a++type SignalGen a = Int -> a++fromList :: [a] -> Signal a+fromList = (!!)++toList :: Signal a -> [a]+toList s = map s [0..]++start :: SignalGen (Signal a) -> [a]+start g = toList (g 0)++delay :: a -> Signal a -> SignalGen (Signal a)+delay x0 s t_start t_sample+ | t_start < t_sample = s (t_sample-1)+ | t_start == t_sample = x0+ | otherwise = error "This signal doesn't exist yet."++generator :: Signal (SignalGen a) -> SignalGen (Signal a)+generator s _t_start t_sample = s t_sample t_sample++snapshot :: Signal a -> SignalGen a+snapshot = id++memo :: Signal a -> SignalGen (Signal a)+memo = const++stateful :: a -> (a -> a) -> SignalGen (Signal a)+stateful x0 f = mfix $ \sig -> delay x0 (f <$> sig)++transfer :: a -> (t -> a -> a) -> Signal t -> SignalGen (Signal a)+transfer x0 f s = mfix $ \sig -> do+ sig' <- delay x0 sig+ memo (liftA2 f s sig')++transfer2 :: a -> (t1 -> t2 -> a -> a) -> Signal t1 -> Signal t2 -> SignalGen (Signal a)+transfer2 x0 f s1 s2 = mfix $ \sig -> do+ sig' <- delay x0 sig+ memo (liftA3 f s1 s2 sig')++transfer3 :: a -> (t1 -> t2 -> t3 -> a -> a) -> Signal t1 -> Signal t2 -> Signal t3 -> SignalGen (Signal a)+transfer3 x0 f s1 s2 s3 = mfix $ \sig -> do+ sig' <- delay x0 sig+ memo (liftM4 f s1 s2 s3 sig')++transfer4 :: a -> (t1 -> t2 -> t3 -> t4 -> a -> a) -> Signal t1 -> Signal t2 -> Signal t3 -> Signal t4 -> SignalGen (Signal a)+transfer4 x0 f s1 s2 s3 s4 = mfix $ \sig -> do+ sig' <- delay x0 sig+ memo (liftM5 f s1 s2 s3 s4 sig')
elerea.cabal view
@@ -1,5 +1,5 @@ Name: elerea-Version: 2.6.0+Version: 2.7.0 Cabal-Version: >= 1.2 Synopsis: A minimalistic FRP library Category: reactivity, FRP@@ -36,6 +36,8 @@ The basic idea of the implementation is described in the WFLP 2010 paper /Efficient and Compositional Higher-Order Streams/ (<http://sgate.emt.bme.hu/documents/patai/publications/PataiWFLP2010.pdf>).+ .+ Additional contributions: Takano Akio Author: Patai Gergely Maintainer: Patai Gergely (patai.gergely@gmail.com)@@ -51,6 +53,7 @@ Exposed-Modules: FRP.Elerea FRP.Elerea.Simple+ FRP.Elerea.Simple.Pure FRP.Elerea.Param FRP.Elerea.Clocked