@@ -3,6 +3,7 @@
3{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleContexts #-}
4{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE FlexibleInstances #-}
5{-# LANGUAGE GADTs #-}
5{-# LANGUAGE GADTs #-}
6+{-# LANGUAGE ScopedTypeVariables #-}
6{-# LANGUAGE MultiParamTypeClasses #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
7{-# LANGUAGE RankNTypes #-}
8{-# LANGUAGE RankNTypes #-}
8{-# LANGUAGE RecursiveDo #-}
9{-# LANGUAGE RecursiveDo #-}
@@ -23,6 +24,24 @@ import Data.Monoid
24import Prelude
25import Prelude
27+pushDyn :: (Reflex t, MonadHold t m) => (a -> PushM t b) -> Dynamic t a -> m (Dynamic t b)
28+pushDyn f d = buildDynamic (sample (current d) >>= f) (pushAlways f (updated d))
30+foldedDyn :: (Reflex t, MonadHold t m) => (a -> a -> a) -> Dynamic t a -> m (Dynamic t a)
31+foldedDyn f d = fmap join $ flip buildDynamic never $ do
32+ a <- sample (current d)
33+ foldDyn f a (updated d)
35+scannedDyn :: (Reflex t, MonadHold t m) => Dynamic t a -> m (Dynamic t [a])
36+scannedDyn = fmap (fmap reverse) . foldedDyn (<>) . fmap pure
38+scanInnerDyns :: (Reflex t, MonadHold t m) => Dynamic t (Dynamic t a) -> m (Dynamic t [a])
40+ scans <- scannedDyn d
41+ return (join (fmap distributeListOverDynPure scans))
26{-# ANN testCases "HLint: ignore Functor law" #-}
45{-# ANN testCases "HLint: ignore Functor law" #-}
27testCases :: [(String, TestCase)]
46testCases :: [(String, TestCase)]
28testCases =
47testCases =
@@ -201,6 +220,14 @@ testCases =
201 bb <- hold (constant "x") $ pushAlways (const $ hold "a" eo) eo
220 bb <- hold (constant "x") $ pushAlways (const $ hold "a" eo) eo
202 return $ pull $ sample =<< sample bb
221 return $ pull $ sample =<< sample bb
224+ , testB "foldDynWhileFiring" $ do
226+ d <- foldDyn (:) [] $
227+ pushAlways (\a -> foldDyn (:) [a] e) e
229+ return $ current (join (fmap distributeListOverDynPure d))
204 , testE "joinDyn" $ do
231 , testE "joinDyn" $ do
205 e <- events1
232 e <- events1
206 bb <- hold "b" e
233 bb <- hold "b" e
@@ -223,6 +250,38 @@ testCases =
223 d2 <- fmap (fmap (map toUpper)) $ foldDyn (++) "0" =<< events2
250 d2 <- fmap (fmap (map toUpper)) $ foldDyn (++) "0" =<< events2
225 return $ current $ zipDynWith (<>) d1 d2
252 return $ current $ zipDynWith (<>) d1 d2
254+ , testB "buildDynamicStrictness" $ do
256+ d'' <- pushDyn return d'
257+ d' <- pushDyn return d
258+ d <- holdDyn "0" =<< events1
260+ _ <- sample (current d'')
261+ return (current d'')
263+ , testB "factorDyn" $ do
264+ d <- holdDyn (Left "a") =<< eithers
266+ eithers <- eitherDyn d
267+ let unFactor = either id id
268+ return $ current (join (fmap unFactor eithers))
270+ , testB "pushDynDeep" $ do
274+ d1 <- holdDyn "d1" =<< events1
275+ d2 <- holdDyn "d2" =<< events2
277+ d <- flip pushDyn d1 $ \a ->
278+ flip pushDyn d2 $ \b ->
279+ flip pushDyn d1 $ \c ->
280+ return (a <> b <> c)
282+ d' <- pushDyn scanInnerDyns d >>= scanInnerDyns
226 , testE "fan-1" $ do
285 , testE "fan-1" $ do
227 e <- fmap toMap <$> events1
286 e <- fmap toMap <$> events1
228 let es = select (fanMap e) . Const2 <$> values
287 let es = select (fanMap e) . Const2 <$> values
@@ -264,14 +323,18 @@ testCases =
264 return $ void e
323 return $ void e
269 events1, events2, events3 :: TestPlan t m => m (Event t String)
329 events1, events2, events3 :: TestPlan t m => m (Event t String)
270 events1 = plan [(1, "a"), (2, "b"), (5, "c"), (7, "d"), (8, "e")]
330 events1 = plan [(1, "a"), (2, "b"), (5, "c"), (7, "d"), (8, "e")]
271 events2 = plan [(1, "e"), (3, "d"), (4, "c"), (6, "b"), (7, "a")]
331 events2 = plan [(1, "e"), (3, "d"), (4, "c"), (6, "b"), (7, "a")]
273 events3 = liftA2 mappend events1 events2
332 events3 = liftA2 mappend events1 events2
334+ eithers :: TestPlan t m => m (Event t (Either String String))
335+ eithers = plan [(1, Left "e"), (3, Left "d"), (4, Right "c"), (6, Right "b"), (7, Left "a")]
275 values = "abcde"
338 values = "abcde"
276 toMap str = Map.fromList $ map (\c -> (c, c)) str
339 toMap str = Map.fromList $ map (\c -> (c, c)) str
@@ -281,5 +344,3 @@ testCases =
282 deep e = leftmost [e, e]
345 deep e = leftmost [e, e]
283 leftmost2 e1 e2 = leftmost [e1, e2]
346 leftmost2 e1 e2 = leftmost [e1, e2]