packages feed

reflex 0.6.4.1 → 0.7.0.0

raw patch · 11 files changed

+112/−27 lines, 11 filesnew-uploader

Files

ChangeLog.md view
@@ -1,5 +1,14 @@ # Revision history for reflex +## 0.7.0.0++* Add lifting instances for most classes to `Reflex.Profiled.Profiled`. ([#398](https://github.com/reflex-frp/reflex/pull/398))+* Class `MonadQuery t q m` now has a `Monad m` superclass constraint. ([#400](https://github.com/reflex-frp/reflex/pull/400))+* **(Breaking change)** Rename class `MonadBehaviorWriter` -> `BehaviorWriter` for consistency with `EventWriter`/`DynamicWriter`. ([#401](https://github.com/reflex-frp/reflex/pull/401))+* Introduce deprecated alias `MonadBehaviorWriter = BehaviorWriter`. ([#401](https://github.com/reflex-frp/reflex/pull/401))+* Fix bug in spider where event subscriptions would be prematurely finalized due to over-aggressive inlining. ([#409](https://github.com/reflex-frp/reflex/pull/409))+* Add instances of `PerformEvent` and `TriggerEvent` for `MaybeT`. ([#395](https://github.com/reflex-frp/reflex/pull/395))+ ## 0.6.4.1  * Fix a bug in the Reflex Profiled transformer where
README.md view
@@ -21,5 +21,11 @@  ### Hacking -Use the `./scripts/hack-on reflex` script in [Reflex Platform](https://github.com/reflex-frp/reflex-platform) to checkout the source code of `reflex` locally in `reflex-platform/reflex` directory.-Then do modifications to the source in place, and use the `./try-reflex` or `./scripts/work-on` scripts to create the shell to test your changes.+From the root of a [Reflex+Platform](https://github.com/reflex-frp/reflex-platform) checkout, run+`./scripts/hack-on haskell-overlays/reflex-packages/dep/reflex`. This+will check out the reflex source code into the+`haskell-overlays/reflex-packages/dep/reflex` directory. You can then+point that checkout at your fork, make changes, etc. Use the+`./try-reflex` or `./scripts/work-on` scripts to start a shell in+which you can test your changes.
reflex.cabal view
@@ -1,5 +1,5 @@ Name: reflex-Version: 0.6.4.1+Version: 0.7.0.0 Synopsis: Higher-order Functional Reactive Programming Description: Reflex is a high-performance, deterministic, higher-order Functional Reactive Programming system License: BSD3
src/Reflex/BehaviorWriter/Base.hs view
@@ -1,6 +1,6 @@ {-| Module: Reflex.BehaviorWriter.Base-Description: Implementation of MonadBehaviorWriter+Description: Implementation of BehaviorWriter -} {-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleInstances #-}@@ -46,7 +46,7 @@ import Reflex.Requester.Class import Reflex.TriggerEvent.Class --- | A basic implementation of 'MonadBehaviorWriter'.+-- | A basic implementation of 'BehaviorWriter'. newtype BehaviorWriterT t w m a = BehaviorWriterT { unBehaviorWriterT :: StateT [Behavior t w] m a }   deriving (Functor, Applicative, Monad, MonadIO, MonadFix, MonadAsyncException, MonadException) -- The list is kept in reverse order @@ -89,7 +89,7 @@   newEventWithTrigger = lift . newEventWithTrigger   newFanEventWithTrigger f = lift $ newFanEventWithTrigger f -instance (Monad m, Monoid w, Reflex t) => MonadBehaviorWriter t w (BehaviorWriterT t w m) where+instance (Monad m, Monoid w, Reflex t) => BehaviorWriter t w (BehaviorWriterT t w m) where   tellBehavior w = BehaviorWriterT $ modify (w :)  instance MonadReader r m => MonadReader r (BehaviorWriterT t w m) where
src/Reflex/BehaviorWriter/Class.hs view
@@ -1,8 +1,9 @@ {-| Module: Reflex.BehaviorWriter.Class-Description: This module defines the 'MonadBehaviorWriter' class+Description: This module defines the 'BehaviorWriter' class -} {-# LANGUAGE CPP #-}+{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE UndecidableInstances #-}@@ -10,16 +11,21 @@ {-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-} #endif module Reflex.BehaviorWriter.Class-  ( MonadBehaviorWriter (..)+  ( MonadBehaviorWriter+  , BehaviorWriter(..)   ) where  import Control.Monad.Reader (ReaderT, lift) import Reflex.Class (Behavior) --- | 'MonadBehaviorWriter' efficiently collects 'Behavior' values using 'tellBehavior'+{-# DEPRECATED MonadBehaviorWriter "Use 'BehaviorWriter' instead" #-}+-- | Type synonym for 'BehaviorWriter'+type MonadBehaviorWriter = BehaviorWriter++-- | 'BehaviorWriter' efficiently collects 'Behavior' values using 'tellBehavior' -- and combines them monoidally to provide a 'Behavior' result.-class (Monad m, Monoid w) => MonadBehaviorWriter t w m | m -> t w where+class (Monad m, Monoid w) => BehaviorWriter t w m | m -> t w where   tellBehavior :: Behavior t w -> m () -instance MonadBehaviorWriter t w m => MonadBehaviorWriter t w (ReaderT r m) where+instance BehaviorWriter t w m => BehaviorWriter t w (ReaderT r m) where   tellBehavior = lift . tellBehavior
src/Reflex/FastWeak.hs view
@@ -151,6 +151,16 @@  -- | Create a 'FastWeakTicket' directly from a value, creating a 'FastWeak' in the process -- which can be obtained with 'getFastWeakTicketValue'.+--+-- This function is marked NOINLINE so it is opaque to GHC.+-- If we do not do this, then GHC will sometimes fuse the constructor away+-- so any weak references that are attached to the ticket will have their+-- finalizer run. Using the opaque constructor, GHC does not see the+-- constructor application, so it behaves like an IORef and cannot be fused away.+--+-- The result is also evaluated to WHNF, since forcing a thunk invalidates+-- the weak pointer to it in some cases.+{-# NOINLINE mkFastWeakTicket #-} mkFastWeakTicket :: a -> IO (FastWeakTicket a) -- I think it's fine if this is lazy - it'll retain the 'a', but so would the output; we just need to make sure it's forced before we start relying on the -- associated FastWeak to actually be weak
src/Reflex/PerformEvent/Class.hs view
@@ -22,6 +22,7 @@ import Reflex.TriggerEvent.Class  import Control.Monad.Reader+import Control.Monad.Trans.Maybe (MaybeT (..))  -- | 'PerformEvent' represents actions that can trigger other actions based on -- 'Event's.@@ -61,3 +62,8 @@   performEvent e = do     r <- ask     lift $ performEvent $ flip runReaderT r <$> e++instance PerformEvent t m => PerformEvent t (MaybeT m) where+  type Performable (MaybeT m) = MaybeT (Performable m)+  performEvent_ = lift . performEvent_ . fmapCheap (void . runMaybeT)+  performEvent = lift . fmap (fmapMaybe id) . performEvent . fmapCheap runMaybeT
src/Reflex/Profiled.hs view
@@ -26,6 +26,7 @@ import Control.Monad.Reader import Control.Monad.Ref import Control.Monad.State.Strict (StateT, execStateT, modify)+import Data.Bifunctor import Data.Coerce import Data.Dependent.Map (DMap, GCompare) import Data.FastMutableIntMap@@ -42,12 +43,20 @@ import GHC.Foreign import GHC.IO.Encoding import GHC.Stack+import Reflex.Adjustable.Class+import Reflex.BehaviorWriter.Class import Reflex.Class+import Reflex.DynamicWriter.Class+import Reflex.EventWriter.Class import Reflex.Host.Class+import Reflex.NotReady.Class import Reflex.PerformEvent.Class+import Reflex.PostBuild.Class+import Reflex.Query.Class+import Reflex.Requester.Class+import Reflex.TriggerEvent.Class  import System.IO.Unsafe-import Unsafe.Coerce  data ProfiledTimeline t @@ -178,6 +187,16 @@ instance MonadSample t m => MonadSample (ProfiledTimeline t) (ProfiledM m) where   sample (Behavior_Profiled b) = ProfiledM $ sample b +instance Adjustable t m => Adjustable (ProfiledTimeline t) (ProfiledM m) where+  runWithReplace a0 a' = (fmap . fmap) coerce . lift $+    runWithReplace (coerce a0) (coerce $ coerce <$> a')+  traverseIntMapWithKeyWithAdjust f dm0 dm' = (fmap . fmap) coerce . lift $+    traverseIntMapWithKeyWithAdjust (\k v -> coerce $ f k v) dm0 (coerce dm')+  traverseDMapWithKeyWithAdjust f dm0 dm' = (fmap . fmap) coerce . lift $+    traverseDMapWithKeyWithAdjust (\k v -> coerce $ f k v) dm0 (coerce dm')+  traverseDMapWithKeyWithAdjustWithMove f dm0 dm' = (fmap . fmap) coerce . lift $+    traverseDMapWithKeyWithAdjustWithMove (\k v -> coerce $ f k v) dm0 (coerce dm')+ instance MonadTrans ProfiledM where   lift = ProfiledM @@ -188,6 +207,39 @@   type Performable (ProfiledM m) = Performable m   performEvent_ = lift . performEvent_ . coerce   performEvent = lift . fmap coerce . performEvent . coerce++instance TriggerEvent t m => TriggerEvent (ProfiledTimeline t) (ProfiledM m) where+  newTriggerEvent = first coerce <$> lift newTriggerEvent+  newTriggerEventWithOnComplete = first coerce <$> lift newTriggerEventWithOnComplete+  newEventWithLazyTriggerWithOnComplete f = coerce <$> lift (newEventWithLazyTriggerWithOnComplete f)++instance PostBuild t m => PostBuild (ProfiledTimeline t) (ProfiledM m) where+  getPostBuild = coerce <$> lift getPostBuild++instance NotReady t m => NotReady (ProfiledTimeline t) (ProfiledM m) where+  notReady = lift notReady+  notReadyUntil = lift . notReadyUntil . coerce++instance BehaviorWriter t w m => BehaviorWriter (ProfiledTimeline t) w (ProfiledM m) where+  tellBehavior = lift . tellBehavior . coerce++instance DynamicWriter t w m => DynamicWriter (ProfiledTimeline t) w (ProfiledM m) where+  tellDyn = lift . tellDyn . coerce++instance EventWriter t w m => EventWriter (ProfiledTimeline t) w (ProfiledM m) where+  tellEvent = lift . tellEvent . coerce++instance MonadQuery t q m => MonadQuery (ProfiledTimeline t) q (ProfiledM m) where+  tellQueryIncremental = lift . tellQueryIncremental . coerce+  askQueryResult = coerce <$> lift askQueryResult+  queryIncremental = fmap coerce . lift . queryIncremental . coerce++instance Requester t m => Requester (ProfiledTimeline t) (ProfiledM m) where+  type Request (ProfiledM m) = Request m+  type Response (ProfiledM m) = Response m++  requesting = fmap coerce . lift . requesting . coerce+  requesting_ = lift . requesting_ . coerce  instance MonadRef m => MonadRef (ProfiledM m) where   type Ref (ProfiledM m) = Ref m
src/Reflex/Query/Class.hs view
@@ -125,7 +125,7 @@  instance Additive SelectedCount --- | The Semigroup/Monoid/Group instances for a Query containing 'SelectedCount's should use+-- | The Semigroup\/Monoid\/Group instances for a Query containing 'SelectedCount's should use -- this function which returns Nothing if the result is 0. This allows the pruning of leaves -- of the 'Query' that are no longer wanted. combineSelectedCounts :: SelectedCount -> SelectedCount -> Maybe SelectedCount@@ -133,12 +133,12 @@  -- | A class that allows sending of 'Query's and retrieval of 'QueryResult's. See 'queryDyn' for a commonly -- used interface.-class (Group q, Additive q, Query q) => MonadQuery t q m | m -> q t where+class (Group q, Additive q, Query q, Monad m) => MonadQuery t q m | m -> q t where   tellQueryIncremental :: Incremental t (AdditivePatch q) -> m ()   askQueryResult :: m (Dynamic t (QueryResult q))   queryIncremental :: Incremental t (AdditivePatch q) -> m (Dynamic t (QueryResult q)) -instance (Monad m, MonadQuery t q m) => MonadQuery t q (ReaderT r m) where+instance MonadQuery t q m => MonadQuery t q (ReaderT r m) where   tellQueryIncremental = lift . tellQueryIncremental   askQueryResult = lift askQueryResult   queryIncremental = lift . queryIncremental@@ -148,11 +148,11 @@ tellQueryDyn d = tellQueryIncremental $ unsafeBuildIncremental (sample (current d)) $ attachWith (\old new -> AdditivePatch $ new ~~ old) (current d) (updated d)  -- | Retrieve 'Dynamic'ally updating 'QueryResult's for a 'Dynamic'ally updating 'Query'.-queryDyn :: (Reflex t, Monad m, MonadQuery t q m) => Dynamic t q -> m (Dynamic t (QueryResult q))+queryDyn :: (Reflex t, MonadQuery t q m) => Dynamic t q -> m (Dynamic t (QueryResult q)) queryDyn q = do   tellQueryDyn q   zipDynWith crop q <$> askQueryResult  -- | Use a query morphism to operate on a smaller version of a query.-subQuery :: (Reflex t, MonadQuery t q2 m, Monad m) => QueryMorphism q1 q2 -> Dynamic t q1 -> m (Dynamic t (QueryResult q1))+subQuery :: (Reflex t, MonadQuery t q2 m) => QueryMorphism q1 q2 -> Dynamic t q1 -> m (Dynamic t (QueryResult q1)) subQuery (QueryMorphism f g) x = fmap g <$> queryDyn (fmap f x)
src/Reflex/Spider/Internal.hs view
@@ -450,16 +450,6 @@   , subscriberRecalculateHeight :: !(Height -> IO ())   } ---TODO: Move this comment to WeakBag--- These function are constructor functions that are marked NOINLINE so they are--- opaque to GHC. If we do not do this, then GHC will sometimes fuse the constructor away--- so any weak references that are attached to the constructors will have their--- finalizer run. Using the opaque constructor, does not see the--- constructor application, so it behaves like an IORef and cannot be fused away.------ The result is also evaluated to WHNF, since forcing a thunk invalidates--- the weak pointer to it in some cases.- newSubscriberHold :: (HasSpiderTimeline x, Patch p) => Hold x p -> IO (Subscriber x p) newSubscriberHold h = return $ Subscriber   { subscriberPropagate = {-# SCC "traverseHold" #-} propagateSubscriberHold h
src/Reflex/TriggerEvent/Class.hs view
@@ -12,6 +12,7 @@ import Control.Monad.Reader import Control.Monad.State import qualified Control.Monad.State.Strict as Strict+import Control.Monad.Trans.Maybe (MaybeT)  --TODO: Shouldn't have IO hard-coded -- | 'TriggerEvent' represents actions that can create 'Event's that can be@@ -44,6 +45,11 @@   newEventWithLazyTriggerWithOnComplete = lift . newEventWithLazyTriggerWithOnComplete  instance TriggerEvent t m => TriggerEvent t (Strict.StateT s m) where+  newTriggerEvent = lift newTriggerEvent+  newTriggerEventWithOnComplete = lift newTriggerEventWithOnComplete+  newEventWithLazyTriggerWithOnComplete = lift . newEventWithLazyTriggerWithOnComplete++instance TriggerEvent t m => TriggerEvent t (MaybeT m) where   newTriggerEvent = lift newTriggerEvent   newTriggerEventWithOnComplete = lift newTriggerEventWithOnComplete   newEventWithLazyTriggerWithOnComplete = lift . newEventWithLazyTriggerWithOnComplete