@@ -6,6 +6,13 @@
66{-# LANGUAGE MultiParamTypeClasses #-}
77{-# LANGUAGE TypeFamilies #-}
88{-# LANGUAGE UndecidableInstances #-}
9+-- |
10+-- Module:
11+-- Reflex.Query.Class
12+-- Description:
13+-- A class that ties together queries to some data source and their results,
14+-- providing methods for requesting data from the source and accumulating
15+-- streamed results.
916module Reflex.Query.Class
1017 ( Query (..)
1118 , QueryMorphism (..)
@@ -32,6 +39,10 @@ import Foreign.Storable
3239
3340import Reflex.Class
3441
42+-- | A 'Query' can be thought of as a declaration of interest in some set of data.
43+-- A 'QueryResult' is the set of data associated with that interest set.
44+-- The @crop@ function provides a way to determine what part of a given 'QueryResult'
45+-- is relevant to a given 'Query'.
3546class (Monoid (QueryResult a), Semigroup (QueryResult a)) => Query a where
3647 type QueryResult a :: *
3748 crop :: a -> QueryResult a -> QueryResult a
@@ -40,8 +51,8 @@ instance (Ord k, Query v) => Query (MonoidalMap k v) where
4051 type QueryResult (MonoidalMap k v) = MonoidalMap k (QueryResult v)
4152 crop q r = MonoidalMap.intersectionWith (flip crop) r q
4253
43−-- | NB: QueryMorphism's must be group homomorphisms when acting on the query type
44−-- and compatible with the query relationship when acting on the query result
54+-- | QueryMorphism's must be group homomorphisms when acting on the query type
55+-- and compatible with the query relationship when acting on the query result.
4556data QueryMorphism q q' = QueryMorphism
4657 { _queryMorphism_mapQuery :: q -> q'
4758 , _queryMorphism_mapQueryResult :: QueryResult q' -> QueryResult q
@@ -54,13 +65,16 @@ instance Category QueryMorphism where
5465 , _queryMorphism_mapQueryResult = mapQueryResult qm' . mapQueryResult qm
5566 }
5667
68+-- | Apply a 'QueryMorphism' to a 'Query'
5769mapQuery :: QueryMorphism q q' -> q -> q'
5870mapQuery = _queryMorphism_mapQuery
5971
72+-- | Map a 'QueryMorphism' to a 'QueryResult'
6073mapQueryResult :: QueryMorphism q q' -> QueryResult q' -> QueryResult q
6174mapQueryResult = _queryMorphism_mapQueryResult
6275
63−-- | This type keeps track of the multiplicity of elements of the view selector that are being used by the app
76+-- | This type can be used to track of the frequency of interest in a given 'Query'. See note on
77+-- 'combineSelectedCounts'
6478newtype SelectedCount = SelectedCount { unSelectedCount :: Int }
6579 deriving (Eq, Ord, Show, Read, Integral, Num, Bounded, Enum, Real, Ix, Bits, FiniteBits, Storable, Data)
6680
@@ -76,10 +90,14 @@ instance Group SelectedCount where
7690
7791instance Additive SelectedCount
7892
79−-- | The Semigroup/Monoid/Group instances for a ViewSelector should use this function which returns Nothing if the result is 0. This allows the pruning of leaves that are no longer wanted.
93+-- | The Semigroup/Monoid/Group instances for a Query containing 'SelectedCount's should use
94+-- this function which returns Nothing if the result is 0. This allows the pruning of leaves
95+-- of the 'Query' that are no longer wanted.
8096combineSelectedCounts :: SelectedCount -> SelectedCount -> Maybe SelectedCount
8197combineSelectedCounts (SelectedCount i) (SelectedCount j) = if i == negate j then Nothing else Just $ SelectedCount (i + j)
8298
99+-- | A class that allows sending of 'Query's and retrieval of 'QueryResult's. See 'queryDyn' for a commonly
100+-- used interface.
83101class (Group q, Additive q, Query q) => MonadQuery t q m | m -> q t where
84102 tellQueryIncremental :: Incremental t (AdditivePatch q) -> m ()
85103 askQueryResult :: m (Dynamic t (QueryResult q))
@@ -90,9 +108,11 @@ instance (Monad m, MonadQuery t q m) => MonadQuery t q (ReaderT r m) where
90108 askQueryResult = lift askQueryResult
91109 queryIncremental = lift . queryIncremental
92110
111+-- | Produce and send an 'Incremental' 'Query' from a 'Dynamic' 'Query'.
93112tellQueryDyn :: (Reflex t, MonadQuery t q m) => Dynamic t q -> m ()
94113tellQueryDyn d = tellQueryIncremental $ unsafeBuildIncremental (sample (current d)) $ attachWith (\old new -> AdditivePatch $ new ~~ old) (current d) (updated d)
95114
115+-- | Retrieve 'Dynamic'ally updating 'QueryResult's for a 'Dynamic'ally updating 'Query'.
96116queryDyn :: (Reflex t, Monad m, MonadQuery t q m) => Dynamic t q -> m (Dynamic t (QueryResult q))
97117queryDyn q = do
98118 tellQueryDyn q