on develop help sign in
Merge pull request #294 from reflex-frp/release/0.6.1

Release/0.6.1

commit898efd6f5bd1529f722c88800ab2dc7189440785 authorAli Abrar <aliabrar@gmail.com> dateThu 28 Mar 2019, 14:57 (8 years ago) parenta083a7666004a0
8 files changed+134−10
ChangeLog.md+5 default.nix+1−1 reflex.cabal+1−1 src/Data/AppendMap.hs+4−5 src/Reflex/Dynamic.hs+1−1 src/Reflex/FunctorMaybe.hs+2 test/EventWriterT.hs+18 test/RequesterT.hs+102−2
ChangeLog.md+5
@@ -10,3 +10,8 @@
1010* Add withRequesterT to map functions over the request and response of a RequesterT.
1111* Suppress nil patches in QueryT as an optimization. The Query type must now have an Eq instance.
1212* Add throttleBatchWithLag to Reflex.Time. See that module for details.
13+
14+## 0.6.1.0
15+
16+* Re-export all of Data.Map.Monoidal
17+* Fix QueryT and RequesterT tests
default.nix+1−1
@@ -11,7 +11,7 @@
1111}:
1212mkDerivation {
1313 pname = "reflex";
14− version = "0.5.0.1";
14+ version = "0.6.1";
1515 src = builtins.filterSource (path: type: !(builtins.elem (baseNameOf path) [ ".git" "dist" ])) ./.;
1616 libraryHaskellDepends = [
1717 base bifunctors containers dependent-map dependent-sum
reflex.cabal+1−1
@@ -1,5 +1,5 @@
11Name: reflex
2−Version: 0.6
2+Version: 0.6.1
33Synopsis: Higher-order Functional Reactive Programming
44Description: Reflex is a high-performance, deterministic, higher-order Functional Reactive Programming system
55License: BSD3
src/Data/AppendMap.hs+4−5
@@ -26,9 +26,8 @@ import qualified Data.Map.Internal.Debug as Map (showTree, showTreeWith)
2626#else
2727import qualified Data.Map as Map (showTree, showTreeWith)
2828#endif
29−import Data.Witherable (Filterable(..))
30−import Data.Map.Monoidal (MonoidalMap(..), delete, null, empty)
31−import qualified Data.Map.Monoidal as M
29+import qualified Data.Witherable as W
30+import Data.Map.Monoidal
3231
3332{-# DEPRECATED AppendMap "Use 'MonoidalMap' instead" #-}
3433type AppendMap = MonoidalMap
@@ -40,8 +39,8 @@ _unAppendMap = getMonoidalMap
4039pattern AppendMap :: Map k v -> MonoidalMap k v
4140pattern AppendMap m = MonoidalMap m
4241
43−instance Filterable (MonoidalMap k) where
44− mapMaybe = M.mapMaybe
42+instance W.Filterable (MonoidalMap k) where
43+ mapMaybe = mapMaybe
4544
4645-- | Deletes a key, returning 'Nothing' if the result is empty.
4746nonEmptyDelete :: Ord k => k -> MonoidalMap k a -> Maybe (MonoidalMap k a)
src/Reflex/Dynamic.hs+1−1
@@ -219,7 +219,7 @@ distributeListOverDynPure =
219219-- | Combine a 'Dynamic' of a 'Map' of 'Dynamic's into a 'Dynamic'
220220-- with the current values of the 'Dynamic's in a map.
221221joinDynThroughMap :: forall t k a. (Reflex t, Ord k) => Dynamic t (Map k (Dynamic t a)) -> Dynamic t (Map k a)
222−joinDynThroughMap = join . fmap distributeMapOverDynPure
222+joinDynThroughMap = (distributeMapOverDynPure =<<)
223223
224224-- | Print the value of the 'Dynamic' when it is first read and on each
225225-- subsequent change that is observed (as 'traceEvent'), prefixed with the
src/Reflex/FunctorMaybe.hs+2
@@ -1,6 +1,8 @@
11{-# LANGUAGE CPP #-}
2+#if MIN_VERSION_base(4,9,0)
23{-# LANGUAGE GeneralizedNewtypeDeriving #-}
34{-# LANGUAGE StandaloneDeriving #-}
5+#endif
46
57-- |
68-- Module:
test/EventWriterT.hs+18
@@ -1,3 +1,4 @@
1+{-# LANGUAGE BangPatterns #-}
12{-# LANGUAGE FlexibleContexts #-}
23{-# LANGUAGE GADTs #-}
34{-# LANGUAGE RecursiveDo #-}
@@ -36,6 +37,9 @@ main = do
3637 print os4
3738 os5@[[Nothing, Just [1, 2]]] <- runApp' (unwrapApp testLiveTellEventDMap) [Just ()]
3839 print os5
40+ os6 <- runApp' (unwrapApp delayedPulse) [Just ()]
41+ print os6
42+ let ![[Nothing, Nothing]] = os6
3943 return ()
4044
4145unwrapApp :: (Reflex t, Monad m) => (a -> EventWriterT t [Int] m ()) -> a -> m (Event t [Int])
@@ -112,3 +116,17 @@ testLiveTellEventDMap pulse = do
112116 (mapToDMap $ M.singleton 1 ())
113117 ((PatchDMap $ DMap.map (ComposeMaybe . Just) $ mapToDMap $ M.singleton 2 ()) <$ pulse)
114118 return ()
119+
120+delayedPulse
121+ :: forall t m
122+ . ( Reflex t
123+ , Adjustable t m
124+ , MonadHold t m
125+ , MonadFix m
126+ )
127+ => Event t ()
128+ -> EventWriterT t [Int] m ()
129+delayedPulse pulse = void $ flip runWithReplace (pure () <$ pulse) $ do
130+ -- This has the effect of delaying pulse' from pulse
131+ (_, pulse') <- runWithReplace (pure ()) $ pure [1] <$ pulse
132+ tellEvent pulse'
test/RequesterT.hs+102−2
@@ -2,13 +2,17 @@
22{-# LANGUAGE FlexibleContexts #-}
33{-# LANGUAGE GADTs #-}
44{-# LANGUAGE RankNTypes #-}
5+{-# LANGUAGE RecursiveDo #-}
56{-# LANGUAGE ScopedTypeVariables #-}
67module Main where
78
89import Control.Lens
910import Control.Monad
11+import Control.Monad.Fix
1012import qualified Data.Dependent.Map as DMap
1113import Data.Dependent.Sum
14+import Data.Functor.Misc
15+import qualified Data.Map as M
1216import Data.These
1317
1418import Reflex
@@ -25,7 +29,6 @@ main = do
2529 [ Just ()
2630 ]
2731 print os1
28− let ![[Just [10,9,8,7,6,5,4,3,2,1]]] = os1
2932 os2 <- runApp' (unwrapApp testSimultaneous) $ map Just $
3033 [ This ()
3134 , That ()
@@ -33,7 +36,20 @@ main = do
3336 , These () ()
3437 ]
3538 print os2
36− let ![[Just [1,3,5,7,9]],[Nothing,Nothing],[Just [2,4,6,8,10]],[Just [2,4,6,8,10],Nothing]] = os2
39+ os3 <- runApp' (unwrapApp testMoribundRequest) [Just ()]
40+ print os3
41+ os4 <- runApp' (unwrapApp testMoribundRequestDMap) [Just ()]
42+ print os4
43+ os5 <- runApp' (unwrapApp testLiveRequestDMap) [Just ()]
44+ print os5
45+ os6 <- runApp' (unwrapApp delayedPulse) [Just ()]
46+ print os6
47+ let ![[Just [1,2,3,4,5,6,7,8,9,10]]] = os1 -- The order is reversed here: see the documentation for 'runRequesterT'
48+ let ![[Just [9,7,5,3,1]],[Nothing,Nothing],[Just [10,8,6,4,2]],[Just [10,8,6,4,2],Nothing]] = os2
49+ let ![[Nothing, Just [2]]] = os3
50+ let ![[Nothing, Just [2]]] = os4
51+ let ![[Nothing, Just [1, 2]]] = os5
52+ -- let ![[Nothing, Nothing]] = os6 -- TODO re-enable this test after issue #233 has been resolved
3753 return ()
3854
3955unwrapRequest :: DSum tag RequestInt -> Int
@@ -67,3 +83,87 @@ testSimultaneous pulse = do
6783 switchE = fmapMaybe (^? there) pulse
6884 forM_ [1,3..9] $ \i -> runWithReplace (requestingIdentity (RequestInt i <$ tellE)) $ ffor switchE $ \_ ->
6985 requestingIdentity (RequestInt (i+1) <$ tellE)
86+
87+-- | Test that a widget requesting and event which fires at the same time it has been replaced
88+-- doesn't count along with the new widget.
89+testMoribundRequest
90+ :: forall t m
91+ . ( Reflex t
92+ , Adjustable t m
93+ , MonadHold t m
94+ , MonadFix m
95+ , Response m ~ Identity
96+ , Request m ~ RequestInt
97+ , Requester t m
98+ )
99+ => Event t ()
100+ -> m ()
101+testMoribundRequest pulse = do
102+ rec let requestIntOnReplace x = requestingIdentity $ RequestInt x <$ rwrFinished
103+ (_, rwrFinished) <- runWithReplace (requestIntOnReplace 1) $ requestIntOnReplace 2 <$ pulse
104+ return ()
105+
106+-- | The equivalent of 'testMoribundRequest' for 'traverseDMapWithKeyWithAdjust'.
107+testMoribundRequestDMap
108+ :: forall t m
109+ . ( Reflex t
110+ , Adjustable t m
111+ , MonadHold t m
112+ , MonadFix m
113+ , Response m ~ Identity
114+ , Request m ~ RequestInt
115+ , Requester t m
116+ )
117+ => Event t ()
118+ -> m ()
119+testMoribundRequestDMap pulse = do
120+ rec let requestIntOnReplace :: Int -> m ()
121+ requestIntOnReplace x = void $ requestingIdentity $ RequestInt x <$ rwrFinished
122+ (_, rwrFinished :: Event t (PatchDMap (Const2 () Int) Identity)) <-
123+ traverseDMapWithKeyWithAdjust
124+ (\(Const2 ()) (Identity v) -> Identity . const v <$> requestIntOnReplace v)
125+ (mapToDMap $ M.singleton () 1)
126+ ((PatchDMap $ DMap.map (ComposeMaybe . Just) $ mapToDMap $ M.singleton () 2) <$ pulse)
127+ return ()
128+
129+-- | Ensures that elements which are _not_ removed can still fire requests
130+-- during the same frame as other elements are updated.
131+testLiveRequestDMap
132+ :: forall t m
133+ . ( Reflex t
134+ , Adjustable t m
135+ , MonadHold t m
136+ , MonadFix m
137+ , Response m ~ Identity
138+ , Request m ~ RequestInt
139+ , Requester t m
140+ )
141+ => Event t ()
142+ -> m ()
143+testLiveRequestDMap pulse = do
144+ rec let requestIntOnReplace :: Int -> m ()
145+ requestIntOnReplace x = void $ requestingIdentity $ RequestInt x <$ rwrFinished
146+ (_, rwrFinished :: Event t (PatchDMap (Const2 Int ()) Identity)) <-
147+ traverseDMapWithKeyWithAdjust
148+ (\(Const2 k) (Identity ()) -> Identity <$> requestIntOnReplace k)
149+ (mapToDMap $ M.singleton 1 ())
150+ ((PatchDMap $ DMap.map (ComposeMaybe . Just) $ mapToDMap $ M.singleton 2 ()) <$ pulse)
151+ return ()
152+
153+delayedPulse
154+ :: forall t m
155+ . ( Reflex t
156+ , Adjustable t m
157+ , MonadHold t m
158+ , MonadFix m
159+ , Response m ~ Identity
160+ , Request m ~ RequestInt
161+ , PerformEvent t m
162+ , Requester t m
163+ )
164+ => Event t ()
165+ -> m ()
166+delayedPulse pulse = void $ flip runWithReplace (pure () <$ pulse) $ do
167+ -- This has the effect of delaying pulse' from pulse
168+ (_, pulse') <- runWithReplace (pure ()) $ pure (RequestInt 1) <$ pulse
169+ requestingIdentity pulse'