{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
-- |
-- Module:
--   Reflex.Query.Class
-- Description:
--   A class that ties together queries to some data source and their results,
--   providing methods for requesting data from the source and accumulating
--   streamed results.
module Reflex.Query.Class
  ( Query (..)
  , QueryMorphism (..)
  , SelectedCount (..)
  , combineSelectedCounts

  , MonadQuery (..)
  , tellQueryDyn
  , queryDyn
  , subQuery
  , mapQuery
  , mapQueryResult
  ) where

import Control.Applicative
import Control.Category (Category)
import qualified Control.Category as Cat
import Control.Monad.Reader
import Data.Bits
import Data.Data
import Data.Ix
import Data.Kind (Type)
import Data.Map.Monoidal (MonoidalMap)
import qualified Data.Map.Monoidal as MonoidalMap
import Data.Semigroup (Semigroup(..))
import Data.Semigroup.Commutative
import Data.Void
import Data.Monoid hiding ((<>))
import Foreign.Storable

import Reflex.Class

-- | A 'Query' can be thought of as a declaration of interest in some set of data.
-- A 'QueryResult' is the set of data associated with that interest set.
-- The @crop@ function provides a way to determine what part of a given 'QueryResult'
-- is relevant to a given 'Query'.
class (Monoid (QueryResult a), Semigroup (QueryResult a)) => Query a where
  type QueryResult a :: Type
  crop :: a -> QueryResult a -> QueryResult a

instance (Ord k, Query v) => Query (MonoidalMap k v) where
  type QueryResult (MonoidalMap k v) = MonoidalMap k (QueryResult v)
  crop :: MonoidalMap k v
-> QueryResult (MonoidalMap k v) -> QueryResult (MonoidalMap k v)
crop MonoidalMap k v
q QueryResult (MonoidalMap k v)
r = (QueryResult v -> v -> QueryResult v)
-> MonoidalMap k (QueryResult v)
-> MonoidalMap k v
-> MonoidalMap k (QueryResult v)
forall k a b c.
Ord k =>
(a -> b -> c)
-> MonoidalMap k a -> MonoidalMap k b -> MonoidalMap k c
MonoidalMap.intersectionWith ((v -> QueryResult v -> QueryResult v)
-> QueryResult v -> v -> QueryResult v
forall a b c. (a -> b -> c) -> b -> a -> c
flip v -> QueryResult v -> QueryResult v
forall a. Query a => a -> QueryResult a -> QueryResult a
crop) MonoidalMap k (QueryResult v)
QueryResult (MonoidalMap k v)
r MonoidalMap k v
q

-- | the result of two queries is both results.
instance (Query a, Query b) => Query (a, b) where
  type QueryResult (a, b) = (QueryResult a, QueryResult b)
  crop :: (a, b) -> QueryResult (a, b) -> QueryResult (a, b)
crop (a
x, b
x') (QueryResult a
y, QueryResult b
y') = (a -> QueryResult a -> QueryResult a
forall a. Query a => a -> QueryResult a -> QueryResult a
crop a
x QueryResult a
y, b -> QueryResult b -> QueryResult b
forall a. Query a => a -> QueryResult a -> QueryResult a
crop b
x' QueryResult b
y')

-- | Trivial queries have trivial results.
instance Query () where
  type QueryResult () = ()
  crop :: () -> QueryResult () -> QueryResult ()
crop ()
_ QueryResult ()
_ = ()

-- | The result of an absurd query is trivial; If you can ask the question, the
-- answer cannot tell you anything you didn't already know.
--
-- 'QueryResult Void = @Void@' seems like it would also work, but that has
-- problems of robustness. In some applications, an unasked question can still
-- be answered, so it is important that the result is inhabited even when the
-- question isn't. Applications that wish to prevent this can mandate that the
-- query result be paired with the query: then the whole response will be
-- uninhabited as desired.
instance Query Void where
  type QueryResult Void = ()
  crop :: Void -> QueryResult Void -> QueryResult Void
crop = Void -> () -> ()
Void -> QueryResult Void -> QueryResult Void
forall a. Void -> a
absurd

#if MIN_VERSION_base(4,12,0)
-- | We can lift queries into monoidal containers.
-- But beware of Applicatives whose monoid is different from (pure mempty, liftA2 mappend)
instance (Query q, Applicative f) => Query (Ap f q) where
  type QueryResult (Ap f q) = Ap f (QueryResult q)
  crop :: Ap f q -> QueryResult (Ap f q) -> QueryResult (Ap f q)
crop = (q -> QueryResult q -> QueryResult q)
-> Ap f q -> Ap f (QueryResult q) -> Ap f (QueryResult q)
forall a b c. (a -> b -> c) -> Ap f a -> Ap f b -> Ap f c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 q -> QueryResult q -> QueryResult q
forall a. Query a => a -> QueryResult a -> QueryResult a
crop
#endif

-- | QueryMorphism's must be group homomorphisms when acting on the query type
-- and compatible with the query relationship when acting on the query result.
data QueryMorphism q q' = QueryMorphism
  { forall q q'. QueryMorphism q q' -> q -> q'
_queryMorphism_mapQuery :: q -> q'
  , forall q q'. QueryMorphism q q' -> QueryResult q' -> QueryResult q
_queryMorphism_mapQueryResult :: QueryResult q' -> QueryResult q
  }

instance Category QueryMorphism where
  id :: forall a. QueryMorphism a a
id = (a -> a) -> (QueryResult a -> QueryResult a) -> QueryMorphism a a
forall q q'.
(q -> q')
-> (QueryResult q' -> QueryResult q) -> QueryMorphism q q'
QueryMorphism a -> a
forall a. a -> a
id QueryResult a -> QueryResult a
forall a. a -> a
id
  QueryMorphism b c
qm . :: forall b c a.
QueryMorphism b c -> QueryMorphism a b -> QueryMorphism a c
. QueryMorphism a b
qm' = QueryMorphism
    { _queryMorphism_mapQuery :: a -> c
_queryMorphism_mapQuery = QueryMorphism b c -> b -> c
forall q q'. QueryMorphism q q' -> q -> q'
mapQuery QueryMorphism b c
qm (b -> c) -> (a -> b) -> a -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QueryMorphism a b -> a -> b
forall q q'. QueryMorphism q q' -> q -> q'
mapQuery QueryMorphism a b
qm'
    , _queryMorphism_mapQueryResult :: QueryResult c -> QueryResult a
_queryMorphism_mapQueryResult = QueryMorphism a b -> QueryResult b -> QueryResult a
forall q q'. QueryMorphism q q' -> QueryResult q' -> QueryResult q
mapQueryResult QueryMorphism a b
qm' (QueryResult b -> QueryResult a)
-> (QueryResult c -> QueryResult b)
-> QueryResult c
-> QueryResult a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QueryMorphism b c -> QueryResult c -> QueryResult b
forall q q'. QueryMorphism q q' -> QueryResult q' -> QueryResult q
mapQueryResult QueryMorphism b c
qm
    }

-- | Apply a 'QueryMorphism' to a 'Query'
mapQuery :: QueryMorphism q q' -> q -> q'
mapQuery :: forall q q'. QueryMorphism q q' -> q -> q'
mapQuery = QueryMorphism q q' -> q -> q'
forall q q'. QueryMorphism q q' -> q -> q'
_queryMorphism_mapQuery

-- | Map a 'QueryMorphism' to a 'QueryResult'
mapQueryResult :: QueryMorphism q q' -> QueryResult q' -> QueryResult q
mapQueryResult :: forall q q'. QueryMorphism q q' -> QueryResult q' -> QueryResult q
mapQueryResult = QueryMorphism q q' -> QueryResult q' -> QueryResult q
forall q q'. QueryMorphism q q' -> QueryResult q' -> QueryResult q
_queryMorphism_mapQueryResult

-- | This type can be used to track of the frequency of interest in a given 'Query'. See note on
-- 'combineSelectedCounts'
newtype SelectedCount = SelectedCount { SelectedCount -> Int
unSelectedCount :: Int }
  deriving (SelectedCount -> SelectedCount -> Bool
(SelectedCount -> SelectedCount -> Bool)
-> (SelectedCount -> SelectedCount -> Bool) -> Eq SelectedCount
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SelectedCount -> SelectedCount -> Bool
== :: SelectedCount -> SelectedCount -> Bool
$c/= :: SelectedCount -> SelectedCount -> Bool
/= :: SelectedCount -> SelectedCount -> Bool
Eq, Eq SelectedCount
Eq SelectedCount
-> (SelectedCount -> SelectedCount -> Ordering)
-> (SelectedCount -> SelectedCount -> Bool)
-> (SelectedCount -> SelectedCount -> Bool)
-> (SelectedCount -> SelectedCount -> Bool)
-> (SelectedCount -> SelectedCount -> Bool)
-> (SelectedCount -> SelectedCount -> SelectedCount)
-> (SelectedCount -> SelectedCount -> SelectedCount)
-> Ord SelectedCount
SelectedCount -> SelectedCount -> Bool
SelectedCount -> SelectedCount -> Ordering
SelectedCount -> SelectedCount -> SelectedCount
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: SelectedCount -> SelectedCount -> Ordering
compare :: SelectedCount -> SelectedCount -> Ordering
$c< :: SelectedCount -> SelectedCount -> Bool
< :: SelectedCount -> SelectedCount -> Bool
$c<= :: SelectedCount -> SelectedCount -> Bool
<= :: SelectedCount -> SelectedCount -> Bool
$c> :: SelectedCount -> SelectedCount -> Bool
> :: SelectedCount -> SelectedCount -> Bool
$c>= :: SelectedCount -> SelectedCount -> Bool
>= :: SelectedCount -> SelectedCount -> Bool
$cmax :: SelectedCount -> SelectedCount -> SelectedCount
max :: SelectedCount -> SelectedCount -> SelectedCount
$cmin :: SelectedCount -> SelectedCount -> SelectedCount
min :: SelectedCount -> SelectedCount -> SelectedCount
Ord, Int -> SelectedCount -> ShowS
[SelectedCount] -> ShowS
SelectedCount -> String
(Int -> SelectedCount -> ShowS)
-> (SelectedCount -> String)
-> ([SelectedCount] -> ShowS)
-> Show SelectedCount
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SelectedCount -> ShowS
showsPrec :: Int -> SelectedCount -> ShowS
$cshow :: SelectedCount -> String
show :: SelectedCount -> String
$cshowList :: [SelectedCount] -> ShowS
showList :: [SelectedCount] -> ShowS
Show, ReadPrec [SelectedCount]
ReadPrec SelectedCount
Int -> ReadS SelectedCount
ReadS [SelectedCount]
(Int -> ReadS SelectedCount)
-> ReadS [SelectedCount]
-> ReadPrec SelectedCount
-> ReadPrec [SelectedCount]
-> Read SelectedCount
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS SelectedCount
readsPrec :: Int -> ReadS SelectedCount
$creadList :: ReadS [SelectedCount]
readList :: ReadS [SelectedCount]
$creadPrec :: ReadPrec SelectedCount
readPrec :: ReadPrec SelectedCount
$creadListPrec :: ReadPrec [SelectedCount]
readListPrec :: ReadPrec [SelectedCount]
Read, Enum SelectedCount
Real SelectedCount
Real SelectedCount
-> Enum SelectedCount
-> (SelectedCount -> SelectedCount -> SelectedCount)
-> (SelectedCount -> SelectedCount -> SelectedCount)
-> (SelectedCount -> SelectedCount -> SelectedCount)
-> (SelectedCount -> SelectedCount -> SelectedCount)
-> (SelectedCount
    -> SelectedCount -> (SelectedCount, SelectedCount))
-> (SelectedCount
    -> SelectedCount -> (SelectedCount, SelectedCount))
-> (SelectedCount -> Integer)
-> Integral SelectedCount
SelectedCount -> Integer
SelectedCount -> SelectedCount -> (SelectedCount, SelectedCount)
SelectedCount -> SelectedCount -> SelectedCount
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
$cquot :: SelectedCount -> SelectedCount -> SelectedCount
quot :: SelectedCount -> SelectedCount -> SelectedCount
$crem :: SelectedCount -> SelectedCount -> SelectedCount
rem :: SelectedCount -> SelectedCount -> SelectedCount
$cdiv :: SelectedCount -> SelectedCount -> SelectedCount
div :: SelectedCount -> SelectedCount -> SelectedCount
$cmod :: SelectedCount -> SelectedCount -> SelectedCount
mod :: SelectedCount -> SelectedCount -> SelectedCount
$cquotRem :: SelectedCount -> SelectedCount -> (SelectedCount, SelectedCount)
quotRem :: SelectedCount -> SelectedCount -> (SelectedCount, SelectedCount)
$cdivMod :: SelectedCount -> SelectedCount -> (SelectedCount, SelectedCount)
divMod :: SelectedCount -> SelectedCount -> (SelectedCount, SelectedCount)
$ctoInteger :: SelectedCount -> Integer
toInteger :: SelectedCount -> Integer
Integral, Integer -> SelectedCount
SelectedCount -> SelectedCount
SelectedCount -> SelectedCount -> SelectedCount
(SelectedCount -> SelectedCount -> SelectedCount)
-> (SelectedCount -> SelectedCount -> SelectedCount)
-> (SelectedCount -> SelectedCount -> SelectedCount)
-> (SelectedCount -> SelectedCount)
-> (SelectedCount -> SelectedCount)
-> (SelectedCount -> SelectedCount)
-> (Integer -> SelectedCount)
-> Num SelectedCount
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: SelectedCount -> SelectedCount -> SelectedCount
+ :: SelectedCount -> SelectedCount -> SelectedCount
$c- :: SelectedCount -> SelectedCount -> SelectedCount
- :: SelectedCount -> SelectedCount -> SelectedCount
$c* :: SelectedCount -> SelectedCount -> SelectedCount
* :: SelectedCount -> SelectedCount -> SelectedCount
$cnegate :: SelectedCount -> SelectedCount
negate :: SelectedCount -> SelectedCount
$cabs :: SelectedCount -> SelectedCount
abs :: SelectedCount -> SelectedCount
$csignum :: SelectedCount -> SelectedCount
signum :: SelectedCount -> SelectedCount
$cfromInteger :: Integer -> SelectedCount
fromInteger :: Integer -> SelectedCount
Num, SelectedCount
SelectedCount -> SelectedCount -> Bounded SelectedCount
forall a. a -> a -> Bounded a
$cminBound :: SelectedCount
minBound :: SelectedCount
$cmaxBound :: SelectedCount
maxBound :: SelectedCount
Bounded, Int -> SelectedCount
SelectedCount -> Int
SelectedCount -> [SelectedCount]
SelectedCount -> SelectedCount
SelectedCount -> SelectedCount -> [SelectedCount]
SelectedCount -> SelectedCount -> SelectedCount -> [SelectedCount]
(SelectedCount -> SelectedCount)
-> (SelectedCount -> SelectedCount)
-> (Int -> SelectedCount)
-> (SelectedCount -> Int)
-> (SelectedCount -> [SelectedCount])
-> (SelectedCount -> SelectedCount -> [SelectedCount])
-> (SelectedCount -> SelectedCount -> [SelectedCount])
-> (SelectedCount
    -> SelectedCount -> SelectedCount -> [SelectedCount])
-> Enum SelectedCount
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: SelectedCount -> SelectedCount
succ :: SelectedCount -> SelectedCount
$cpred :: SelectedCount -> SelectedCount
pred :: SelectedCount -> SelectedCount
$ctoEnum :: Int -> SelectedCount
toEnum :: Int -> SelectedCount
$cfromEnum :: SelectedCount -> Int
fromEnum :: SelectedCount -> Int
$cenumFrom :: SelectedCount -> [SelectedCount]
enumFrom :: SelectedCount -> [SelectedCount]
$cenumFromThen :: SelectedCount -> SelectedCount -> [SelectedCount]
enumFromThen :: SelectedCount -> SelectedCount -> [SelectedCount]
$cenumFromTo :: SelectedCount -> SelectedCount -> [SelectedCount]
enumFromTo :: SelectedCount -> SelectedCount -> [SelectedCount]
$cenumFromThenTo :: SelectedCount -> SelectedCount -> SelectedCount -> [SelectedCount]
enumFromThenTo :: SelectedCount -> SelectedCount -> SelectedCount -> [SelectedCount]
Enum, Num SelectedCount
Ord SelectedCount
Num SelectedCount
-> Ord SelectedCount
-> (SelectedCount -> Rational)
-> Real SelectedCount
SelectedCount -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
$ctoRational :: SelectedCount -> Rational
toRational :: SelectedCount -> Rational
Real, Ord SelectedCount
Ord SelectedCount
-> ((SelectedCount, SelectedCount) -> [SelectedCount])
-> ((SelectedCount, SelectedCount) -> SelectedCount -> Int)
-> ((SelectedCount, SelectedCount) -> SelectedCount -> Int)
-> ((SelectedCount, SelectedCount) -> SelectedCount -> Bool)
-> ((SelectedCount, SelectedCount) -> Int)
-> ((SelectedCount, SelectedCount) -> Int)
-> Ix SelectedCount
(SelectedCount, SelectedCount) -> Int
(SelectedCount, SelectedCount) -> [SelectedCount]
(SelectedCount, SelectedCount) -> SelectedCount -> Bool
(SelectedCount, SelectedCount) -> SelectedCount -> Int
forall a.
Ord a
-> ((a, a) -> [a])
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Bool)
-> ((a, a) -> Int)
-> ((a, a) -> Int)
-> Ix a
$crange :: (SelectedCount, SelectedCount) -> [SelectedCount]
range :: (SelectedCount, SelectedCount) -> [SelectedCount]
$cindex :: (SelectedCount, SelectedCount) -> SelectedCount -> Int
index :: (SelectedCount, SelectedCount) -> SelectedCount -> Int
$cunsafeIndex :: (SelectedCount, SelectedCount) -> SelectedCount -> Int
unsafeIndex :: (SelectedCount, SelectedCount) -> SelectedCount -> Int
$cinRange :: (SelectedCount, SelectedCount) -> SelectedCount -> Bool
inRange :: (SelectedCount, SelectedCount) -> SelectedCount -> Bool
$crangeSize :: (SelectedCount, SelectedCount) -> Int
rangeSize :: (SelectedCount, SelectedCount) -> Int
$cunsafeRangeSize :: (SelectedCount, SelectedCount) -> Int
unsafeRangeSize :: (SelectedCount, SelectedCount) -> Int
Ix, Eq SelectedCount
SelectedCount
Eq SelectedCount
-> (SelectedCount -> SelectedCount -> SelectedCount)
-> (SelectedCount -> SelectedCount -> SelectedCount)
-> (SelectedCount -> SelectedCount -> SelectedCount)
-> (SelectedCount -> SelectedCount)
-> (SelectedCount -> Int -> SelectedCount)
-> (SelectedCount -> Int -> SelectedCount)
-> SelectedCount
-> (Int -> SelectedCount)
-> (SelectedCount -> Int -> SelectedCount)
-> (SelectedCount -> Int -> SelectedCount)
-> (SelectedCount -> Int -> SelectedCount)
-> (SelectedCount -> Int -> Bool)
-> (SelectedCount -> Maybe Int)
-> (SelectedCount -> Int)
-> (SelectedCount -> Bool)
-> (SelectedCount -> Int -> SelectedCount)
-> (SelectedCount -> Int -> SelectedCount)
-> (SelectedCount -> Int -> SelectedCount)
-> (SelectedCount -> Int -> SelectedCount)
-> (SelectedCount -> Int -> SelectedCount)
-> (SelectedCount -> Int -> SelectedCount)
-> (SelectedCount -> Int)
-> Bits SelectedCount
Int -> SelectedCount
SelectedCount -> Bool
SelectedCount -> Int
SelectedCount -> Maybe Int
SelectedCount -> SelectedCount
SelectedCount -> Int -> Bool
SelectedCount -> Int -> SelectedCount
SelectedCount -> SelectedCount -> SelectedCount
forall a.
Eq a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> a
-> (Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> Bool)
-> (a -> Maybe Int)
-> (a -> Int)
-> (a -> Bool)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int)
-> Bits a
$c.&. :: SelectedCount -> SelectedCount -> SelectedCount
.&. :: SelectedCount -> SelectedCount -> SelectedCount
$c.|. :: SelectedCount -> SelectedCount -> SelectedCount
.|. :: SelectedCount -> SelectedCount -> SelectedCount
$cxor :: SelectedCount -> SelectedCount -> SelectedCount
xor :: SelectedCount -> SelectedCount -> SelectedCount
$ccomplement :: SelectedCount -> SelectedCount
complement :: SelectedCount -> SelectedCount
$cshift :: SelectedCount -> Int -> SelectedCount
shift :: SelectedCount -> Int -> SelectedCount
$crotate :: SelectedCount -> Int -> SelectedCount
rotate :: SelectedCount -> Int -> SelectedCount
$czeroBits :: SelectedCount
zeroBits :: SelectedCount
$cbit :: Int -> SelectedCount
bit :: Int -> SelectedCount
$csetBit :: SelectedCount -> Int -> SelectedCount
setBit :: SelectedCount -> Int -> SelectedCount
$cclearBit :: SelectedCount -> Int -> SelectedCount
clearBit :: SelectedCount -> Int -> SelectedCount
$ccomplementBit :: SelectedCount -> Int -> SelectedCount
complementBit :: SelectedCount -> Int -> SelectedCount
$ctestBit :: SelectedCount -> Int -> Bool
testBit :: SelectedCount -> Int -> Bool
$cbitSizeMaybe :: SelectedCount -> Maybe Int
bitSizeMaybe :: SelectedCount -> Maybe Int
$cbitSize :: SelectedCount -> Int
bitSize :: SelectedCount -> Int
$cisSigned :: SelectedCount -> Bool
isSigned :: SelectedCount -> Bool
$cshiftL :: SelectedCount -> Int -> SelectedCount
shiftL :: SelectedCount -> Int -> SelectedCount
$cunsafeShiftL :: SelectedCount -> Int -> SelectedCount
unsafeShiftL :: SelectedCount -> Int -> SelectedCount
$cshiftR :: SelectedCount -> Int -> SelectedCount
shiftR :: SelectedCount -> Int -> SelectedCount
$cunsafeShiftR :: SelectedCount -> Int -> SelectedCount
unsafeShiftR :: SelectedCount -> Int -> SelectedCount
$crotateL :: SelectedCount -> Int -> SelectedCount
rotateL :: SelectedCount -> Int -> SelectedCount
$crotateR :: SelectedCount -> Int -> SelectedCount
rotateR :: SelectedCount -> Int -> SelectedCount
$cpopCount :: SelectedCount -> Int
popCount :: SelectedCount -> Int
Bits, Bits SelectedCount
Bits SelectedCount
-> (SelectedCount -> Int)
-> (SelectedCount -> Int)
-> (SelectedCount -> Int)
-> FiniteBits SelectedCount
SelectedCount -> Int
forall b.
Bits b -> (b -> Int) -> (b -> Int) -> (b -> Int) -> FiniteBits b
$cfiniteBitSize :: SelectedCount -> Int
finiteBitSize :: SelectedCount -> Int
$ccountLeadingZeros :: SelectedCount -> Int
countLeadingZeros :: SelectedCount -> Int
$ccountTrailingZeros :: SelectedCount -> Int
countTrailingZeros :: SelectedCount -> Int
FiniteBits, Ptr SelectedCount -> IO SelectedCount
Ptr SelectedCount -> Int -> IO SelectedCount
Ptr SelectedCount -> Int -> SelectedCount -> IO ()
Ptr SelectedCount -> SelectedCount -> IO ()
SelectedCount -> Int
(SelectedCount -> Int)
-> (SelectedCount -> Int)
-> (Ptr SelectedCount -> Int -> IO SelectedCount)
-> (Ptr SelectedCount -> Int -> SelectedCount -> IO ())
-> (forall b. Ptr b -> Int -> IO SelectedCount)
-> (forall b. Ptr b -> Int -> SelectedCount -> IO ())
-> (Ptr SelectedCount -> IO SelectedCount)
-> (Ptr SelectedCount -> SelectedCount -> IO ())
-> Storable SelectedCount
forall b. Ptr b -> Int -> IO SelectedCount
forall b. Ptr b -> Int -> SelectedCount -> IO ()
forall a.
(a -> Int)
-> (a -> Int)
-> (Ptr a -> Int -> IO a)
-> (Ptr a -> Int -> a -> IO ())
-> (forall b. Ptr b -> Int -> IO a)
-> (forall b. Ptr b -> Int -> a -> IO ())
-> (Ptr a -> IO a)
-> (Ptr a -> a -> IO ())
-> Storable a
$csizeOf :: SelectedCount -> Int
sizeOf :: SelectedCount -> Int
$calignment :: SelectedCount -> Int
alignment :: SelectedCount -> Int
$cpeekElemOff :: Ptr SelectedCount -> Int -> IO SelectedCount
peekElemOff :: Ptr SelectedCount -> Int -> IO SelectedCount
$cpokeElemOff :: Ptr SelectedCount -> Int -> SelectedCount -> IO ()
pokeElemOff :: Ptr SelectedCount -> Int -> SelectedCount -> IO ()
$cpeekByteOff :: forall b. Ptr b -> Int -> IO SelectedCount
peekByteOff :: forall b. Ptr b -> Int -> IO SelectedCount
$cpokeByteOff :: forall b. Ptr b -> Int -> SelectedCount -> IO ()
pokeByteOff :: forall b. Ptr b -> Int -> SelectedCount -> IO ()
$cpeek :: Ptr SelectedCount -> IO SelectedCount
peek :: Ptr SelectedCount -> IO SelectedCount
$cpoke :: Ptr SelectedCount -> SelectedCount -> IO ()
poke :: Ptr SelectedCount -> SelectedCount -> IO ()
Storable, Typeable SelectedCount
Typeable SelectedCount
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> SelectedCount -> c SelectedCount)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c SelectedCount)
-> (SelectedCount -> Constr)
-> (SelectedCount -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c SelectedCount))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c SelectedCount))
-> ((forall b. Data b => b -> b) -> SelectedCount -> SelectedCount)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> SelectedCount -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> SelectedCount -> r)
-> (forall u. (forall d. Data d => d -> u) -> SelectedCount -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> SelectedCount -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> SelectedCount -> m SelectedCount)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> SelectedCount -> m SelectedCount)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> SelectedCount -> m SelectedCount)
-> Data SelectedCount
SelectedCount -> Constr
SelectedCount -> DataType
(forall b. Data b => b -> b) -> SelectedCount -> SelectedCount
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> SelectedCount -> u
forall u. (forall d. Data d => d -> u) -> SelectedCount -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SelectedCount -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SelectedCount -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SelectedCount -> m SelectedCount
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SelectedCount -> m SelectedCount
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SelectedCount
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SelectedCount -> c SelectedCount
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SelectedCount)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SelectedCount)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SelectedCount -> c SelectedCount
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SelectedCount -> c SelectedCount
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SelectedCount
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SelectedCount
$ctoConstr :: SelectedCount -> Constr
toConstr :: SelectedCount -> Constr
$cdataTypeOf :: SelectedCount -> DataType
dataTypeOf :: SelectedCount -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SelectedCount)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SelectedCount)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SelectedCount)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SelectedCount)
$cgmapT :: (forall b. Data b => b -> b) -> SelectedCount -> SelectedCount
gmapT :: (forall b. Data b => b -> b) -> SelectedCount -> SelectedCount
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SelectedCount -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SelectedCount -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SelectedCount -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SelectedCount -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> SelectedCount -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> SelectedCount -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> SelectedCount -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> SelectedCount -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SelectedCount -> m SelectedCount
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SelectedCount -> m SelectedCount
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SelectedCount -> m SelectedCount
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SelectedCount -> m SelectedCount
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SelectedCount -> m SelectedCount
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SelectedCount -> m SelectedCount
Data)

instance Semigroup SelectedCount where
  SelectedCount Int
a <> :: SelectedCount -> SelectedCount -> SelectedCount
<> SelectedCount Int
b = Int -> SelectedCount
SelectedCount (Int
a Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
b)

instance Monoid SelectedCount where
  mempty :: SelectedCount
mempty = Int -> SelectedCount
SelectedCount Int
0
  mappend :: SelectedCount -> SelectedCount -> SelectedCount
mappend = SelectedCount -> SelectedCount -> SelectedCount
forall a. Semigroup a => a -> a -> a
(<>)

instance Group SelectedCount where
  negateG :: SelectedCount -> SelectedCount
negateG (SelectedCount Int
a) = Int -> SelectedCount
SelectedCount (Int -> Int
forall a. Num a => a -> a
negate Int
a)

instance Commutative SelectedCount

-- | 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
combineSelectedCounts :: SelectedCount -> SelectedCount -> Maybe SelectedCount
combineSelectedCounts (SelectedCount Int
i) (SelectedCount Int
j) = if Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> Int
forall a. Num a => a -> a
negate Int
j then Maybe SelectedCount
forall a. Maybe a
Nothing else SelectedCount -> Maybe SelectedCount
forall a. a -> Maybe a
Just (SelectedCount -> Maybe SelectedCount)
-> SelectedCount -> Maybe SelectedCount
forall a b. (a -> b) -> a -> b
$ Int -> SelectedCount
SelectedCount (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
j)

-- | A class that allows sending of 'Query's and retrieval of 'QueryResult's. See 'queryDyn' for a commonly
-- used interface.
class (Group q, Commutative 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 MonadQuery t q m => MonadQuery t q (ReaderT r m) where
  tellQueryIncremental :: Incremental t (AdditivePatch q) -> ReaderT r m ()
tellQueryIncremental = m () -> ReaderT r m ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> ReaderT r m ())
-> (Incremental t (AdditivePatch q) -> m ())
-> Incremental t (AdditivePatch q)
-> ReaderT r m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Incremental t (AdditivePatch q) -> m ()
forall t q (m :: * -> *).
MonadQuery t q m =>
Incremental t (AdditivePatch q) -> m ()
tellQueryIncremental
  askQueryResult :: ReaderT r m (Dynamic t (QueryResult q))
askQueryResult = m (Dynamic t (QueryResult q))
-> ReaderT r m (Dynamic t (QueryResult q))
forall (m :: * -> *) a. Monad m => m a -> ReaderT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m (Dynamic t (QueryResult q))
forall t q (m :: * -> *).
MonadQuery t q m =>
m (Dynamic t (QueryResult q))
askQueryResult
  queryIncremental :: Incremental t (AdditivePatch q)
-> ReaderT r m (Dynamic t (QueryResult q))
queryIncremental = m (Dynamic t (QueryResult q))
-> ReaderT r m (Dynamic t (QueryResult q))
forall (m :: * -> *) a. Monad m => m a -> ReaderT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m (Dynamic t (QueryResult q))
 -> ReaderT r m (Dynamic t (QueryResult q)))
-> (Incremental t (AdditivePatch q)
    -> m (Dynamic t (QueryResult q)))
-> Incremental t (AdditivePatch q)
-> ReaderT r m (Dynamic t (QueryResult q))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Incremental t (AdditivePatch q) -> m (Dynamic t (QueryResult q))
forall t q (m :: * -> *).
MonadQuery t q m =>
Incremental t (AdditivePatch q) -> m (Dynamic t (QueryResult q))
queryIncremental

-- | Produce and send an 'Incremental' 'Query' from a 'Dynamic' 'Query'.
tellQueryDyn :: (Reflex t, MonadQuery t q m) => Dynamic t q -> m ()
tellQueryDyn :: forall t q (m :: * -> *).
(Reflex t, MonadQuery t q m) =>
Dynamic t q -> m ()
tellQueryDyn Dynamic t q
d = Incremental t (AdditivePatch q) -> m ()
forall t q (m :: * -> *).
MonadQuery t q m =>
Incremental t (AdditivePatch q) -> m ()
tellQueryIncremental (Incremental t (AdditivePatch q) -> m ())
-> Incremental t (AdditivePatch q) -> m ()
forall a b. (a -> b) -> a -> b
$ PullM t (PatchTarget (AdditivePatch q))
-> Event t (AdditivePatch q) -> Incremental t (AdditivePatch q)
forall p.
Patch p =>
PullM t (PatchTarget p) -> Event t p -> Incremental t p
forall {k} (t :: k) p.
(Reflex t, Patch p) =>
PullM t (PatchTarget p) -> Event t p -> Incremental t p
unsafeBuildIncremental (Behavior t q -> PullM t q
forall a. Behavior t a -> PullM t a
forall {k} (t :: k) (m :: * -> *) a.
MonadSample t m =>
Behavior t a -> m a
sample (Dynamic t q -> Behavior t q
forall a. Dynamic t a -> Behavior t a
forall {k} (t :: k) a. Reflex t => Dynamic t a -> Behavior t a
current Dynamic t q
d)) (Event t (AdditivePatch q) -> Incremental t (AdditivePatch q))
-> Event t (AdditivePatch q) -> Incremental t (AdditivePatch q)
forall a b. (a -> b) -> a -> b
$ (q -> q -> AdditivePatch q)
-> Behavior t q -> Event t q -> Event t (AdditivePatch q)
forall {k} (t :: k) a b c.
Reflex t =>
(a -> b -> c) -> Behavior t a -> Event t b -> Event t c
attachWith (\q
old q
new -> q -> AdditivePatch q
forall p. p -> AdditivePatch p
AdditivePatch (q -> AdditivePatch q) -> q -> AdditivePatch q
forall a b. (a -> b) -> a -> b
$ q
new q -> q -> q
forall q. Group q => q -> q -> q
~~ q
old) (Dynamic t q -> Behavior t q
forall a. Dynamic t a -> Behavior t a
forall {k} (t :: k) a. Reflex t => Dynamic t a -> Behavior t a
current Dynamic t q
d) (Dynamic t q -> Event t q
forall a. Dynamic t a -> Event t a
forall {k} (t :: k) a. Reflex t => Dynamic t a -> Event t a
updated Dynamic t q
d)

-- | Retrieve 'Dynamic'ally updating 'QueryResult's for a 'Dynamic'ally updating 'Query'.
queryDyn :: (Reflex t, MonadQuery t q m) => Dynamic t q -> m (Dynamic t (QueryResult q))
queryDyn :: forall t q (m :: * -> *).
(Reflex t, MonadQuery t q m) =>
Dynamic t q -> m (Dynamic t (QueryResult q))
queryDyn Dynamic t q
q = do
  Dynamic t q -> m ()
forall t q (m :: * -> *).
(Reflex t, MonadQuery t q m) =>
Dynamic t q -> m ()
tellQueryDyn Dynamic t q
q
  (q -> QueryResult q -> QueryResult q)
-> Dynamic t q
-> Dynamic t (QueryResult q)
-> Dynamic t (QueryResult q)
forall {k} (t :: k) a b c.
Reflex t =>
(a -> b -> c) -> Dynamic t a -> Dynamic t b -> Dynamic t c
zipDynWith q -> QueryResult q -> QueryResult q
forall a. Query a => a -> QueryResult a -> QueryResult a
crop Dynamic t q
q (Dynamic t (QueryResult q) -> Dynamic t (QueryResult q))
-> m (Dynamic t (QueryResult q)) -> m (Dynamic t (QueryResult q))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (Dynamic t (QueryResult q))
forall t q (m :: * -> *).
MonadQuery t q m =>
m (Dynamic t (QueryResult q))
askQueryResult

-- | Use a query morphism to operate on a smaller version of a query.
subQuery :: (Reflex t, MonadQuery t q2 m) => QueryMorphism q1 q2 -> Dynamic t q1 -> m (Dynamic t (QueryResult q1))
subQuery :: forall t q2 (m :: * -> *) q1.
(Reflex t, MonadQuery t q2 m) =>
QueryMorphism q1 q2
-> Dynamic t q1 -> m (Dynamic t (QueryResult q1))
subQuery (QueryMorphism q1 -> q2
f QueryResult q2 -> QueryResult q1
g) Dynamic t q1
x = (QueryResult q2 -> QueryResult q1)
-> Dynamic t (QueryResult q2) -> Dynamic t (QueryResult q1)
forall a b. (a -> b) -> Dynamic t a -> Dynamic t b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap QueryResult q2 -> QueryResult q1
g (Dynamic t (QueryResult q2) -> Dynamic t (QueryResult q1))
-> m (Dynamic t (QueryResult q2)) -> m (Dynamic t (QueryResult q1))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Dynamic t q2 -> m (Dynamic t (QueryResult q2))
forall t q (m :: * -> *).
(Reflex t, MonadQuery t q m) =>
Dynamic t q -> m (Dynamic t (QueryResult q))
queryDyn ((q1 -> q2) -> Dynamic t q1 -> Dynamic t q2
forall a b. (a -> b) -> Dynamic t a -> Dynamic t b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap q1 -> q2
f Dynamic t q1
x)