on develop help sign in
Merge branch 'develop' into cleanup-debug
fabac7dJames Deikun
ChangeLog.md+2
@@ -9,6 +9,8 @@
9* The `Reflex.Patch.*` modules were moved to the `patch` library.
9* The `Reflex.Patch.*` modules were moved to the `patch` library.
10 They are `Data.Patch.*` there, but reexported under their old names for backwards compatability here.
10 They are `Data.Patch.*` there, but reexported under their old names for backwards compatability here.
11
11
12+* Additional instances for `Query` classes for basic types.
13+
12## 0.6.3
14## 0.6.3
13
15
14* `Data.WeakBag.traverse` and `Data.FastWeakBag.traverse` have been deprecated.
16* `Data.WeakBag.traverse` and `Data.FastWeakBag.traverse` have been deprecated.
reflex.cabal+1−1
@@ -72,7 +72,7 @@ library
72 lens >= 4.7 && < 5,
72 lens >= 4.7 && < 5,
73 monad-control >= 1.0.1 && < 1.1,
73 monad-control >= 1.0.1 && < 1.1,
74 mtl >= 2.1 && < 2.3,
74 mtl >= 2.1 && < 2.3,
75− patch >= 0.0 && < 0.1,
75+ patch >= 0.0.1 && < 0.1,
76 prim-uniq >= 0.1.0.1 && < 0.2,
76 prim-uniq >= 0.1.0.1 && < 0.2,
77 primitive >= 0.5 && < 0.8,
77 primitive >= 0.5 && < 0.8,
78 profunctors >= 5.3 && < 5.6,
78 profunctors >= 5.3 && < 5.6,
src/Reflex/Query/Class.hs+40
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
1{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE FlexibleInstances #-}
@@ -21,6 +22,7 @@ module Reflex.Query.Class
21 , MonadQuery (..)
22 , MonadQuery (..)
22 , tellQueryDyn
23 , tellQueryDyn
23 , queryDyn
24 , queryDyn
25+ , subQuery
24 , mapQuery
26 , mapQuery
25 , mapQueryResult
27 , mapQueryResult
26 ) where
28 ) where
@@ -35,6 +37,9 @@ import Data.Map.Monoidal (MonoidalMap)
35import qualified Data.Map.Monoidal as MonoidalMap
37import qualified Data.Map.Monoidal as MonoidalMap
36import Data.Semigroup (Semigroup(..))
38import Data.Semigroup (Semigroup(..))
37import Foreign.Storable
39import Foreign.Storable
40+import Data.Void
41+import Data.Monoid hiding ((<>))
42+import Control.Applicative
38
43
39import Reflex.Class
44import Reflex.Class
40
45
@@ -50,6 +55,37 @@ instance (Ord k, Query v) => Query (MonoidalMap k v) where
50 type QueryResult (MonoidalMap k v) = MonoidalMap k (QueryResult v)
55 type QueryResult (MonoidalMap k v) = MonoidalMap k (QueryResult v)
51 crop q r = MonoidalMap.intersectionWith (flip crop) r q
56 crop q r = MonoidalMap.intersectionWith (flip crop) r q
52
57
58+-- | the result of two queries is both results.
59+instance (Query a, Query b) => Query (a, b) where
60+ type QueryResult (a, b) = (QueryResult a, QueryResult b)
61+ crop (x, x') (y, y') = (crop x y, crop x' y')
62+
63+-- | Trivial queries have trivial results.
64+instance Query () where
65+ type QueryResult () = ()
66+ crop _ _ = ()
67+
68+-- | The result of an absurd query is trivial; If you can ask the question, the
69+-- answer cannot tell you anything you didn't already know.
70+--
71+-- 'QueryResult Void = @Void@' seems like it would also work, but that has
72+-- problems of robustness. In some applications, an unasked question can still
73+-- be answered, so it is important that the result is inhabited even when the
74+-- question isn't. Applications that wish to prevent this can mandate that the
75+-- query result be paired with the query: then the whole response will be
76+-- uninhabited as desired.
77+instance Query Void where
78+ type QueryResult Void = ()
79+ crop = absurd
80+
81+#if MIN_VERSION_base(4,12,0)
82+-- | We can lift queries into monoidal containers.
83+-- But beware of Applicatives whose monoid is different from (pure mempty, liftA2 mappend)
84+instance (Query q, Applicative f) => Query (Ap f q) where
85+ type QueryResult (Ap f q) = Ap f (QueryResult q)
86+ crop = liftA2 crop
87+#endif
88+
53-- | QueryMorphism's must be group homomorphisms when acting on the query type
89-- | QueryMorphism's must be group homomorphisms when acting on the query type
54-- and compatible with the query relationship when acting on the query result.
90-- and compatible with the query relationship when acting on the query result.
55data QueryMorphism q q' = QueryMorphism
91data QueryMorphism q q' = QueryMorphism
@@ -116,3 +152,7 @@ queryDyn :: (Reflex t, Monad m, MonadQuery t q m) => Dynamic t q -> m (Dynamic t
116queryDyn q = do
152queryDyn q = do
117 tellQueryDyn q
153 tellQueryDyn q
118 zipDynWith crop q <$> askQueryResult
154 zipDynWith crop q <$> askQueryResult
155+
156+-- | Use a query morphism to operate on a smaller version of a query.
157+subQuery :: (Reflex t, MonadQuery t q2 m, Monad m) => QueryMorphism q1 q2 -> Dynamic t q1 -> m (Dynamic t (QueryResult q1))
158+subQuery (QueryMorphism f g) x = fmap g <$> queryDyn (fmap f x)