Skip to content

Commit da669e3

Browse files
committed
Merge remote-tracking branch 'origin/develop' into queryt-optimization
* origin/develop: (52 commits) Rename MonadDynamicWriter Add changelog Add Num instance for Dynamic Bump to version 0.6 Re-export mapMaybe from Filterable Update Collection.hs Remove some more long-deprecated functions Organize exports under correct headings Fix warnings Deprecate FunctorMaybe in favor of Filterable Unorphan MonoidalMap Group and Additive instances Remove some long-deprecated functions Add some docs Add matchResponsesWithRequests Add withRequesterT Bump version in default.nix Bump version to 0.5.0.1 Relax bounds on 'these', add explicit import to avoid clash Update the types of merge and fan Add missing haddock hyperlinks ...
2 parents 512e4ea + 767faa1 commit da669e3

40 files changed

+1011
-560
lines changed

ChangeLog.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Revision history for reflex
2+
3+
## 0.6.0.0 -- 2019-03-20
4+
5+
* Deprecate FunctorMaybe in favor of Data.Witherable.Filterable. We still export fmapMaybe, ffilter, etc., but they all rely on Filterable now.
6+
* Rename MonadDynamicWriter to DynamicWriter and add a deprecation for the old name.
7+
* Remove many deprecated functions
8+
* Add a Num instance for Dynamic
9+
* Add matchRequestsWithResponses to make it easier to use Requester with protocols that don't do this matching for you
10+
* Add withRequesterT to map functions over the request and response of a RequesterT

Quickref.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,15 @@ Since MonadHold depends on MonadSample, any [S] function also runs in [H] contex
5757
[ ] mergeWith :: (a -> a -> a) -> [Event a] -> Event a
5858
[ ] leftmost :: [Event a] -> Event a
5959
[ ] mergeList :: [Event a] -> Event (NonEmpty a)
60-
[ ] merge :: GCompare k => DMap (WrapArg Event k) -> Event (DMap k)
60+
[ ] merge :: GCompare k => DMap k Event -> Event (DMap k Identity)
6161
[ ] mergeMap :: Ord k => Map k (Event a) -> Event (Map k a)
6262

6363
-- Efficient one-to-many fanout
64-
[ ] fanMap :: Ord k => Event (Map k a) -> EventSelector (Const2 k a)
65-
[ ] fan :: GCompare k => Event (DMap k) -> EventSelector k
66-
[ ] select :: EventSelector k -> k a -> Event a
67-
[ ] fanEither :: Event (Either a b) -> (Event a, Event b)
68-
[ ] fanThese :: Event (These a b) -> (Event a, Event b)
64+
[ ] fanMap :: Ord k => Event (Map k a) -> EventSelector (Const2 k a)
65+
[ ] fan :: GCompare k => Event (DMap k Identity) -> EventSelector k
66+
[ ] select :: EventSelector k -> k a -> Event a
67+
[ ] fanEither :: Event (Either a b) -> (Event a, Event b)
68+
[ ] fanThese :: Event (These a b) -> (Event a, Event b)
6969

7070
-- Event to Event via function that can sample current values
7171
[ ] push :: (a -> m (Maybe b)) -> Event a -> Event b

README.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
1-
## Reflex
1+
## [Reflex](https://reflex-frp.org/)
22
### Practical Functional Reactive Programming
33

44
Reflex is an fully-deterministic, higher-order Functional Reactive Programming (FRP) interface and an engine that efficiently implements that interface.
55

66
[Reflex-DOM](https://github.com/reflex-frp/reflex-dom) is a framework built on Reflex that facilitates the development of web pages, including highly-interactive single-page apps.
77

8-
Comprehensive documentation is still a work in progress, but a tutorial for Reflex and Reflex-DOM is available at https://github.com/reflex-frp/reflex-platform and an introductory talk given at the New York Haskell Meetup is available here: [Part 1](https://www.youtube.com/watch?v=mYvkcskJbc4) / [Part 2](https://www.youtube.com/watch?v=3qfc9XFVo2c).
9-
108
A summary of Reflex functions is available in the [quick reference](Quickref.md).
119

12-
### Additional resources
10+
**Visit https://reflex-frp.org/ for more information, tutorials, documentation and [examples](https://examples.reflex-frp.org/).**
11+
12+
### Resources
1313
[Get started with Reflex](https://github.com/reflex-frp/reflex-platform)
1414

1515
[/r/reflexfrp](https://www.reddit.com/r/reflexfrp)
1616

1717
[hackage](https://hackage.haskell.org/package/reflex)
1818

1919
[irc.freenode.net #reflex-frp](http://webchat.freenode.net?channels=%23reflex-frp&uio=d4)
20+
21+
### Hacking
22+
23+
Use the `./scripts/hackon 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.
24+
Then do modifications to the source in place, and use the `./tryreflex` or `./scripts/workon` scripts to create the shell to test your changes.

default.nix

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
, template-haskell , these, time, transformers
77
, transformers-compat, unbounded-delays, prim-uniq
88
, data-default, filepath, directory, filemanip, ghcjs-base
9-
, monoidal-containers
9+
, monoidal-containers, witherable
1010
, useTemplateHaskell ? true
1111
}:
1212
mkDerivation {
1313
pname = "reflex";
14-
version = "0.5";
14+
version = "0.5.0.1";
1515
src = builtins.filterSource (path: type: !(builtins.elem (baseNameOf path) [ ".git" "dist" ])) ./.;
1616
libraryHaskellDepends = [
1717
base bifunctors containers dependent-map dependent-sum
@@ -21,7 +21,7 @@ mkDerivation {
2121
transformers-compat prim-uniq
2222
base bifunctors containers deepseq dependent-map dependent-sum
2323
mtl ref-tf split transformers data-default
24-
random time unbounded-delays monoidal-containers
24+
random time unbounded-delays monoidal-containers witherable
2525
] ++ (if ghc.isGhcjs or false then [
2626
ghcjs-base
2727
] else []) ++ (if !useTemplateHaskell then [] else [

reflex.cabal

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Name: reflex
2-
Version: 0.5
2+
Version: 0.6
33
Synopsis: Higher-order Functional Reactive Programming
44
Description: Reflex is a high-performance, deterministic, higher-order Functional Reactive Programming system
55
License: BSD3
@@ -12,6 +12,10 @@ Build-type: Simple
1212
Cabal-version: >=1.9.2
1313
homepage: https://reflex-frp.org
1414
bug-reports: https://github.com/reflex-frp/reflex/issues
15+
extra-source-files:
16+
README.md
17+
Quickref.md
18+
ChangeLog.md
1519

1620
flag use-reflex-optimizer
1721
description: Use the GHC plugin Reflex.Optimizer on some of the modules in the package. This is still experimental.
@@ -37,7 +41,7 @@ library
3741
hs-source-dirs: src
3842
build-depends:
3943
MemoTrie == 0.6.*,
40-
base >= 4.7 && < 4.13,
44+
base >= 4.9 && < 4.13,
4145
bifunctors >= 5.2 && < 5.6,
4246
comonad,
4347
containers >= 0.5 && < 0.7,
@@ -57,11 +61,12 @@ library
5761
semigroups >= 0.16 && < 0.19,
5862
stm >= 2.4 && < 2.6,
5963
syb >= 0.5 && < 0.8,
60-
these >= 0.4 && < 0.8,
64+
these >= 0.4 && < 0.7.7,
6165
time >= 1.4 && < 1.9,
6266
transformers >= 0.2,
6367
transformers-compat >= 0.3,
64-
unbounded-delays >= 0.1.0.0 && < 0.2
68+
unbounded-delays >= 0.1.0.0 && < 0.2,
69+
witherable >= 0.2 && < 0.4
6570

6671
exposed-modules:
6772
Data.AppendMap,
@@ -230,14 +235,16 @@ test-suite RequesterT
230235
main-is: RequesterT.hs
231236
hs-source-dirs: test
232237
build-depends: base
238+
, containers
239+
, deepseq >= 1.3 && < 1.5
233240
, dependent-sum
234241
, dependent-map
235242
, lens
243+
, mtl
236244
, these
237245
, transformers
238246
, reflex
239247
, ref-tf
240-
buildable: False
241248
other-modules:
242249
Reflex.TestPlan
243250
Reflex.Plan.Pure

src/Data/AppendMap.hs

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
11
{-# LANGUAGE CPP #-}
2-
{-# LANGUAGE DeriveFunctor #-}
3-
{-# LANGUAGE DeriveGeneric #-}
4-
{-# LANGUAGE DeriveTraversable #-}
52
{-# LANGUAGE FlexibleContexts #-}
63
{-# LANGUAGE FlexibleInstances #-}
7-
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
84
{-# LANGUAGE MultiParamTypeClasses #-}
95
{-# LANGUAGE PatternSynonyms #-}
106
{-# LANGUAGE RoleAnnotations #-}
117
{-# LANGUAGE ScopedTypeVariables #-}
12-
{-# LANGUAGE StandaloneDeriving #-}
138
{-# LANGUAGE TypeFamilies #-}
149
{-# OPTIONS_GHC -fno-warn-orphans #-}
1510
-- | 'Data.Map' with a better 'Monoid' instance
@@ -31,9 +26,9 @@ import qualified Data.Map.Internal.Debug as Map (showTree, showTreeWith)
3126
#else
3227
import qualified Data.Map as Map (showTree, showTreeWith)
3328
#endif
34-
import Data.Map.Monoidal
35-
import Reflex.Class (FunctorMaybe (..))
36-
import Reflex.Patch (Additive, Group (..))
29+
import Data.Witherable (Filterable(..))
30+
import Data.Map.Monoidal (MonoidalMap(..), delete, null, empty)
31+
import qualified Data.Map.Monoidal as M
3732

3833
{-# DEPRECATED AppendMap "Use 'MonoidalMap' instead" #-}
3934
type AppendMap = MonoidalMap
@@ -45,8 +40,8 @@ _unAppendMap = getMonoidalMap
4540
pattern AppendMap :: Map k v -> MonoidalMap k v
4641
pattern AppendMap m = MonoidalMap m
4742

48-
instance FunctorMaybe (MonoidalMap k) where
49-
fmapMaybe = mapMaybe
43+
instance Filterable (MonoidalMap k) where
44+
mapMaybe = M.mapMaybe
5045

5146
-- | Deletes a key, returning 'Nothing' if the result is empty.
5247
nonEmptyDelete :: Ord k => k -> MonoidalMap k a -> Maybe (MonoidalMap k a)
@@ -60,17 +55,12 @@ mapMaybeNoNull :: (a -> Maybe b)
6055
-> MonoidalMap token a
6156
-> Maybe (MonoidalMap token b)
6257
mapMaybeNoNull f as =
63-
let bs = fmapMaybe f as
58+
let bs = mapMaybe f as
6459
in if null bs
6560
then Nothing
6661
else Just bs
6762

6863
-- TODO: Move instances to `Reflex.Patch`
69-
instance (Ord k, Group q) => Group (MonoidalMap k q) where
70-
negateG = map negateG
71-
72-
instance (Ord k, Additive q) => Additive (MonoidalMap k q)
73-
7464
showTree :: forall k a. (Show k, Show a) => MonoidalMap k a -> String
7565
showTree = coerce (Map.showTree :: Map k a -> String)
7666

src/Data/FastWeakBag.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ import Data.IORef
4242
import System.Mem.Weak
4343
#endif
4444

45-
-- | A @FastWeakBag a@ holds a set of values of type @a@, but does not retain them -
46-
-- that is, they can still be garbage-collected. As long as the @a@s remain
45+
-- | A 'FastWeakBag' holds a set of values of type @/a/@, but does not retain them -
46+
-- that is, they can still be garbage-collected. As long as the @/a/@ values remain
4747
-- alive, the 'FastWeakBag' will continue to refer to them.
4848
#ifdef GHCJS_FAST_WEAK
4949
newtype FastWeakBag a = FastWeakBag JSVal

src/Data/Functor/Misc.hs

Lines changed: 1 addition & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,10 @@ module Data.Functor.Misc
3838
, dmapToThese
3939
, eitherToDSum
4040
, dsumToEither
41-
-- * Deprecated functions
42-
, sequenceDmap
43-
, wrapDMap
44-
, rewrapDMap
45-
, unwrapDMap
46-
, unwrapDMapMaybe
47-
, extractFunctorDMap
4841
, ComposeMaybe (..)
4942
) where
5043

51-
import Control.Applicative (Applicative, (<$>))
44+
import Control.Applicative ((<$>))
5245
import Control.Monad.Identity
5346
import Data.Dependent.Map (DMap)
5447
import qualified Data.Dependent.Map as DMap
@@ -249,39 +242,3 @@ newtype ComposeMaybe f a =
249242
ComposeMaybe { getComposeMaybe :: Maybe (f a) } deriving (Show, Eq, Ord)
250243

251244
deriving instance Functor f => Functor (ComposeMaybe f)
252-
253-
--------------------------------------------------------------------------------
254-
-- Deprecated functions
255-
--------------------------------------------------------------------------------
256-
257-
{-# INLINE sequenceDmap #-}
258-
{-# DEPRECATED sequenceDmap "Use 'Data.Dependent.Map.traverseWithKey (\\_ -> fmap Identity)' instead" #-}
259-
-- | Run the actions contained in the 'DMap'
260-
sequenceDmap :: Applicative t => DMap f t -> t (DMap f Identity)
261-
sequenceDmap = DMap.traverseWithKey $ \_ t -> Identity <$> t
262-
263-
{-# DEPRECATED wrapDMap "Use 'Data.Dependent.Map.map (f . runIdentity)' instead" #-}
264-
-- | Replace the 'Identity' functor for a 'DMap''s values with a different functor
265-
wrapDMap :: (forall a. a -> f a) -> DMap k Identity -> DMap k f
266-
wrapDMap f = DMap.map $ f . runIdentity
267-
268-
{-# DEPRECATED rewrapDMap "Use 'Data.Dependent.Map.map' instead" #-}
269-
-- | Replace one functor for a 'DMap''s values with a different functor
270-
rewrapDMap :: (forall (a :: *). f a -> g a) -> DMap k f -> DMap k g
271-
rewrapDMap = DMap.map
272-
273-
{-# DEPRECATED unwrapDMap "Use 'Data.Dependent.Map.map (Identity . f)' instead" #-}
274-
-- | Replace one functor for a 'DMap''s values with the 'Identity' functor
275-
unwrapDMap :: (forall a. f a -> a) -> DMap k f -> DMap k Identity
276-
unwrapDMap f = DMap.map $ Identity . f
277-
278-
{-# DEPRECATED unwrapDMapMaybe "Use 'Data.Dependent.Map.mapMaybeWithKey (\\_ a -> fmap Identity $ f a)' instead" #-}
279-
-- | Like 'unwrapDMap', but possibly delete some values from the DMap
280-
unwrapDMapMaybe :: GCompare k => (forall a. f a -> Maybe a) -> DMap k f -> DMap k Identity
281-
unwrapDMapMaybe f = DMap.mapMaybeWithKey $ \_ a -> Identity <$> f a
282-
283-
{-# DEPRECATED extractFunctorDMap "Use 'mapKeyValuePairsMonotonic (\\(Const2 k :=> Identity v) -> Const2 k :=> v)' instead" #-}
284-
-- | Eliminate the 'Identity' functor in a 'DMap' and replace it with the
285-
-- underlying functor
286-
extractFunctorDMap :: DMap (Const2 k (f v)) Identity -> DMap (Const2 k v) f
287-
extractFunctorDMap = mapKeyValuePairsMonotonic $ \(Const2 k :=> Identity v) -> Const2 k :=> v

src/Data/Map/Misc.hs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{-# LANGUAGE LambdaCase #-}
2+
-- | Additional functions for manipulating 'Map's.
23
module Data.Map.Misc
34
(
45
-- * Working with Maps
@@ -10,20 +11,28 @@ module Data.Map.Misc
1011
) where
1112

1213
import Data.Align
13-
import Data.Either (isLeft)
1414
import Data.Map (Map)
1515
import qualified Data.Map as Map
1616
import Data.Maybe
1717
import Data.Set (Set)
1818
import qualified Data.Set as Set
1919
import Data.These
2020

21+
-- |Produce a @'Map' k (Maybe v)@ by comparing two @'Map' k v@s, @old@ and @new@ respectively. @Just@ represents an association present in @new@ and @Nothing@
22+
-- represents an association only present in @old@ but no longer present in @new@.
23+
--
24+
-- Similar to 'diffMap' but doesn't require 'Eq' on the values, thus can't tell if a value has changed or not.
2125
diffMapNoEq :: (Ord k) => Map k v -> Map k v -> Map k (Maybe v)
2226
diffMapNoEq olds news = flip Map.mapMaybe (align olds news) $ \case
2327
This _ -> Just Nothing
2428
These _ new -> Just $ Just new
2529
That new -> Just $ Just new
2630

31+
-- |Produce a @'Map' k (Maybe v)@ by comparing two @'Map' k v@s, @old@ and @new respectively. @Just@ represents an association present in @new@ and either not
32+
-- present in @old@ or where the value has changed. @Nothing@ represents an association only present in @old@ but no longer present in @new@.
33+
--
34+
-- See also 'diffMapNoEq' for a similar but weaker version which does not require 'Eq' on the values but thus can't indicated a value not changing between
35+
-- @old@ and @new@ with @Nothing@.
2736
diffMap :: (Ord k, Eq v) => Map k v -> Map k v -> Map k (Maybe v)
2837
diffMap olds news = flip Map.mapMaybe (align olds news) $ \case
2938
This _ -> Just Nothing
@@ -32,23 +41,30 @@ diffMap olds news = flip Map.mapMaybe (align olds news) $ \case
3241
| otherwise -> Just $ Just new
3342
That new -> Just $ Just new
3443

44+
-- |Given a @'Map' k (Maybe v)@ representing keys to insert/update (@Just@) or delete (@Nothing@), produce a new map from the given input @'Map' k v@.
45+
--
46+
-- See also 'Reflex.Patch.Map' and 'Reflex.Patch.MapWithMove'.
3547
applyMap :: Ord k => Map k (Maybe v) -> Map k v -> Map k v
3648
applyMap patch old = insertions `Map.union` (old `Map.difference` deletions)
37-
where (deletions, insertions) = mapPartitionEithers $ maybeToEither <$> patch
49+
where (deletions, insertions) = Map.mapEither maybeToEither patch
3850
maybeToEither = \case
3951
Nothing -> Left ()
4052
Just r -> Right r
4153

54+
-- |Split a @'Map' k (Either a b)@ into @Map k a@ and @Map k b@, equivalent to @'Map.mapEither' id@
55+
{-# DEPRECATED mapPartitionEithers "Use 'mapEither' instead" #-}
4256
mapPartitionEithers :: Map k (Either a b) -> (Map k a, Map k b)
43-
mapPartitionEithers m = (fromLeft <$> ls, fromRight <$> rs)
44-
where (ls, rs) = Map.partition isLeft m
45-
fromLeft (Left l) = l
46-
fromLeft _ = error "mapPartitionEithers: fromLeft received a Right value; this should be impossible"
47-
fromRight (Right r) = r
48-
fromRight _ = error "mapPartitionEithers: fromRight received a Left value; this should be impossible"
57+
mapPartitionEithers = Map.mapEither id
4958

50-
-- | Apply a map patch to a set
51-
-- > applyMapKeysSet patch (Map.keysSet m) == Map.keysSet (applyMap patch m)
59+
-- |Given a @'Map' k (Maybe v)@ representing keys to insert/update (@Just@) or delete (@Nothing@), produce a new @'Set' k@ from the given input set.
60+
--
61+
-- Equivalent to:
62+
--
63+
-- @
64+
-- applyMapKeysSet patch ('Map.keysSet' m) == 'Map.keysSet' ('applyMap' patch m)
65+
-- @
66+
--
67+
-- but avoids the intervening @Map@ and needs no values.
5268
applyMapKeysSet :: Ord k => Map k (Maybe v) -> Set k -> Set k
5369
applyMapKeysSet patch old = Map.keysSet insertions `Set.union` (old `Set.difference` Map.keysSet deletions)
5470
where (insertions, deletions) = Map.partition isJust patch

src/Data/WeakBag.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ import qualified Data.IntMap.Strict as IntMap
3131
import Data.IORef
3232
import System.Mem.Weak
3333

34-
-- | A @WeakBag a@ holds a set of values of type @a@, but does not retain them -
35-
-- that is, they can still be garbage-collected. As long as the @a@s remain
34+
-- | A 'WeakBag' holds a set of values of type @/a/@, but does not retain them -
35+
-- that is, they can still be garbage-collected. As long as the @/a/@ values remain
3636
-- alive, the 'WeakBag' will continue to refer to them.
3737
data WeakBag a = WeakBag
3838
{ _weakBag_nextId :: {-# UNPACK #-} !(IORef Int) --TODO: what if this wraps around?

0 commit comments

Comments
 (0)