@@ -33,6 +33,7 @@ module Reflex.Dynamic
33 , attachPromptlyDyn
33 , attachPromptlyDyn
34 , attachPromptlyDynWith
34 , attachPromptlyDynWith
35 , attachPromptlyDynWithMaybe
35 , attachPromptlyDynWithMaybe
37 , scanDynMaybe
38 , scanDynMaybe
38 , holdUniqDyn
39 , holdUniqDyn
@@ -85,21 +86,20 @@ module Reflex.Dynamic
85 , uniqDynBy
86 , uniqDynBy
88−import Prelude hiding (mapM, mapM_)
90import Data.Functor.Misc
89import Data.Functor.Misc
91import Reflex.Class
90import Reflex.Class
93import Control.Applicative ((<*>))
92import Control.Applicative ((<*>))
94−import Control.Monad hiding (forM, forM_, mapM, mapM_)
93+import Control.Monad
95import Control.Monad.Fix
94import Control.Monad.Fix
96−import Control.Monad.Identity hiding (forM, forM_, mapM, mapM_)
95+import Control.Monad.Identity
97import Data.Align
96import Data.Align
98import Data.Dependent.Map (DMap)
97import Data.Dependent.Map (DMap)
99import qualified Data.Dependent.Map as DMap
98import qualified Data.Dependent.Map as DMap
100import Data.Dependent.Sum (DSum (..))
99import Data.Dependent.Sum (DSum (..))
101import Data.GADT.Compare ((:~:) (..), GCompare (..), GEq (..), GOrdering (..))
100import Data.GADT.Compare ((:~:) (..), GCompare (..), GEq (..), GOrdering (..))
102import Data.Map (Map)
101import Data.Map (Map)
103import Data.Monoid
103import Data.Monoid
104import Data.These
104import Data.These
@@ -269,6 +269,24 @@ attachPromptlyDynWithMaybe f d e =
269 These (_, b) a -> f a b -- Both events are firing, so use the newer value
269 These (_, b) a -> f a b -- Both events are firing, so use the newer value
270 That _ -> Nothing -- The tagging event isn't firing, so don't fire
270 That _ -> Nothing -- The tagging event isn't firing, so don't fire
272+-- | Factor a @Dynamic t (Maybe a)@ into a @Dynamic t (Maybe (Dynamic t a))@,
273+-- such that the outer 'Dynamic' is updated only when the 'Maybe''s constructor
274+-- chages from 'Nothing' to 'Just' or vice-versa. Whenever the constructor
275+-- becomes 'Just', an inner 'Dynamic' will be provided, whose value will track
276+-- the 'a' inside the 'Just'; when the constructor becomes 'Nothing', the
277+-- existing inner 'Dynamic' will become constant, and will not change when the
278+-- outer constructor changes back to 'Nothing'.
279+maybeDyn :: forall t a m. (Reflex t, MonadFix m, MonadHold t m) => Dynamic t (Maybe a) -> m (Dynamic t (Maybe (Dynamic t a)))
281+ ma <- sample $ current d
282+ let inner :: forall m'. (MonadFix m', MonadHold t m') => a -> m' (Dynamic t a)
283+ inner a = holdDyn a . fmapMaybe id =<< takeWhileE isJust (updated d)
284+ mInner0 :: Maybe (Dynamic t a) <- mapM inner ma
285+ rec result <- holdDyn mInner0 $ flip push (updated d) $ \new -> do
286+ old <- sample $ current d
287+ if isJust old == isJust new then return Nothing else Just <$> mapM inner new
272--------------------------------------------------------------------------------
290--------------------------------------------------------------------------------
274--------------------------------------------------------------------------------
292--------------------------------------------------------------------------------