{-# 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') (y, 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 -> 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 (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
  { QueryMorphism q q' -> q -> q'
_queryMorphism_mapQuery :: q -> q'
  , QueryMorphism q q' -> QueryResult q' -> QueryResult q
_queryMorphism_mapQueryResult :: QueryResult q' -> QueryResult q
  }

instance Category QueryMorphism where
  id :: 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 . :: QueryMorphism b c -> QueryMorphism a b -> QueryMorphism a c
. QueryMorphism a b
qm' = QueryMorphism :: forall q q'.
(q -> q')
-> (QueryResult q' -> QueryResult q) -> QueryMorphism q q'
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 :: 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 :: 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
/= :: SelectedCount -> SelectedCount -> Bool
$c/= :: SelectedCount -> SelectedCount -> Bool
== :: SelectedCount -> SelectedCount -> Bool
$c== :: 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
min :: SelectedCount -> SelectedCount -> SelectedCount
$cmin :: SelectedCount -> SelectedCount -> SelectedCount
max :: SelectedCount -> SelectedCount -> SelectedCount
$cmax :: SelectedCount -> SelectedCount -> SelectedCount
>= :: SelectedCount -> SelectedCount -> Bool
$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
compare :: SelectedCount -> SelectedCount -> Ordering
$ccompare :: SelectedCount -> SelectedCount -> Ordering
$cp1Ord :: Eq 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
showList :: [SelectedCount] -> ShowS
$cshowList :: [SelectedCount] -> ShowS
show :: SelectedCount -> String
$cshow :: SelectedCount -> String
showsPrec :: Int -> SelectedCount -> ShowS
$cshowsPrec :: Int -> 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
readListPrec :: ReadPrec [SelectedCount]
$creadListPrec :: ReadPrec [SelectedCount]
readPrec :: ReadPrec SelectedCount
$creadPrec :: ReadPrec SelectedCount
readList :: ReadS [SelectedCount]
$creadList :: ReadS [SelectedCount]
readsPrec :: Int -> ReadS SelectedCount
$creadsPrec :: Int -> ReadS 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
toInteger :: SelectedCount -> Integer
$ctoInteger :: SelectedCount -> Integer
divMod :: SelectedCount -> SelectedCount -> (SelectedCount, SelectedCount)
$cdivMod :: SelectedCount -> SelectedCount -> (SelectedCount, SelectedCount)
quotRem :: SelectedCount -> SelectedCount -> (SelectedCount, SelectedCount)
$cquotRem :: SelectedCount -> SelectedCount -> (SelectedCount, SelectedCount)
mod :: SelectedCount -> SelectedCount -> SelectedCount
$cmod :: SelectedCount -> SelectedCount -> SelectedCount
div :: SelectedCount -> SelectedCount -> SelectedCount
$cdiv :: SelectedCount -> SelectedCount -> SelectedCount
rem :: SelectedCount -> SelectedCount -> SelectedCount
$crem :: SelectedCount -> SelectedCount -> SelectedCount
quot :: SelectedCount -> SelectedCount -> SelectedCount
$cquot :: SelectedCount -> SelectedCount -> SelectedCount
$cp2Integral :: Enum SelectedCount
$cp1Integral :: Real SelectedCount
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
fromInteger :: Integer -> SelectedCount
$cfromInteger :: Integer -> SelectedCount
signum :: SelectedCount -> SelectedCount
$csignum :: SelectedCount -> SelectedCount
abs :: SelectedCount -> SelectedCount
$cabs :: SelectedCount -> SelectedCount
negate :: SelectedCount -> SelectedCount
$cnegate :: SelectedCount -> SelectedCount
* :: SelectedCount -> SelectedCount -> SelectedCount
$c* :: SelectedCount -> SelectedCount -> SelectedCount
- :: SelectedCount -> SelectedCount -> SelectedCount
$c- :: SelectedCount -> SelectedCount -> SelectedCount
+ :: SelectedCount -> SelectedCount -> SelectedCount
$c+ :: SelectedCount -> SelectedCount -> SelectedCount
Num, SelectedCount
SelectedCount -> SelectedCount -> Bounded SelectedCount
forall a. a -> a -> Bounded a
maxBound :: SelectedCount
$cmaxBound :: SelectedCount
minBound :: SelectedCount
$cminBound :: 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
enumFromThenTo :: SelectedCount -> SelectedCount -> SelectedCount -> [SelectedCount]
$cenumFromThenTo :: SelectedCount -> SelectedCount -> SelectedCount -> [SelectedCount]
enumFromTo :: SelectedCount -> SelectedCount -> [SelectedCount]
$cenumFromTo :: SelectedCount -> SelectedCount -> [SelectedCount]
enumFromThen :: SelectedCount -> SelectedCount -> [SelectedCount]
$cenumFromThen :: SelectedCount -> SelectedCount -> [SelectedCount]
enumFrom :: SelectedCount -> [SelectedCount]
$cenumFrom :: SelectedCount -> [SelectedCount]
fromEnum :: SelectedCount -> Int
$cfromEnum :: SelectedCount -> Int
toEnum :: Int -> SelectedCount
$ctoEnum :: Int -> SelectedCount
pred :: SelectedCount -> SelectedCount
$cpred :: SelectedCount -> SelectedCount
succ :: SelectedCount -> SelectedCount
$csucc :: 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
toRational :: SelectedCount -> Rational
$ctoRational :: SelectedCount -> Rational
$cp2Real :: Ord SelectedCount
$cp1Real :: Num SelectedCount
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
unsafeRangeSize :: (SelectedCount, SelectedCount) -> Int
$cunsafeRangeSize :: (SelectedCount, SelectedCount) -> Int
rangeSize :: (SelectedCount, SelectedCount) -> Int
$crangeSize :: (SelectedCount, SelectedCount) -> Int
inRange :: (SelectedCount, SelectedCount) -> SelectedCount -> Bool
$cinRange :: (SelectedCount, SelectedCount) -> SelectedCount -> Bool
unsafeIndex :: (SelectedCount, SelectedCount) -> SelectedCount -> Int
$cunsafeIndex :: (SelectedCount, SelectedCount) -> SelectedCount -> Int
index :: (SelectedCount, SelectedCount) -> SelectedCount -> Int
$cindex :: (SelectedCount, SelectedCount) -> SelectedCount -> Int
range :: (SelectedCount, SelectedCount) -> [SelectedCount]
$crange :: (SelectedCount, SelectedCount) -> [SelectedCount]
$cp1Ix :: Ord SelectedCount
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
popCount :: SelectedCount -> Int
$cpopCount :: SelectedCount -> Int
rotateR :: SelectedCount -> Int -> SelectedCount
$crotateR :: SelectedCount -> Int -> SelectedCount
rotateL :: SelectedCount -> Int -> SelectedCount
$crotateL :: SelectedCount -> Int -> SelectedCount
unsafeShiftR :: SelectedCount -> Int -> SelectedCount
$cunsafeShiftR :: SelectedCount -> Int -> SelectedCount
shiftR :: SelectedCount -> Int -> SelectedCount
$cshiftR :: SelectedCount -> Int -> SelectedCount
unsafeShiftL :: SelectedCount -> Int -> SelectedCount
$cunsafeShiftL :: SelectedCount -> Int -> SelectedCount
shiftL :: SelectedCount -> Int -> SelectedCount
$cshiftL :: SelectedCount -> Int -> SelectedCount
isSigned :: SelectedCount -> Bool
$cisSigned :: SelectedCount -> Bool
bitSize :: SelectedCount -> Int
$cbitSize :: SelectedCount -> Int
bitSizeMaybe :: SelectedCount -> Maybe Int
$cbitSizeMaybe :: SelectedCount -> Maybe Int
testBit :: SelectedCount -> Int -> Bool
$ctestBit :: SelectedCount -> Int -> Bool
complementBit :: SelectedCount -> Int -> SelectedCount
$ccomplementBit :: SelectedCount -> Int -> SelectedCount
clearBit :: SelectedCount -> Int -> SelectedCount
$cclearBit :: SelectedCount -> Int -> SelectedCount
setBit :: SelectedCount -> Int -> SelectedCount
$csetBit :: SelectedCount -> Int -> SelectedCount
bit :: Int -> SelectedCount
$cbit :: Int -> SelectedCount
zeroBits :: SelectedCount
$czeroBits :: SelectedCount
rotate :: SelectedCount -> Int -> SelectedCount
$crotate :: SelectedCount -> Int -> SelectedCount
shift :: SelectedCount -> Int -> SelectedCount
$cshift :: SelectedCount -> Int -> SelectedCount
complement :: SelectedCount -> SelectedCount
$ccomplement :: SelectedCount -> SelectedCount
xor :: SelectedCount -> SelectedCount -> SelectedCount
$cxor :: SelectedCount -> SelectedCount -> SelectedCount
.|. :: SelectedCount -> SelectedCount -> SelectedCount
$c.|. :: SelectedCount -> SelectedCount -> SelectedCount
.&. :: SelectedCount -> SelectedCount -> SelectedCount
$c.&. :: SelectedCount -> SelectedCount -> SelectedCount
$cp1Bits :: Eq SelectedCount
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
countTrailingZeros :: SelectedCount -> Int
$ccountTrailingZeros :: SelectedCount -> Int
countLeadingZeros :: SelectedCount -> Int
$ccountLeadingZeros :: SelectedCount -> Int
finiteBitSize :: SelectedCount -> Int
$cfiniteBitSize :: SelectedCount -> Int
$cp1FiniteBits :: Bits SelectedCount
FiniteBits, Ptr b -> Int -> IO SelectedCount
Ptr b -> Int -> SelectedCount -> IO ()
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
poke :: Ptr SelectedCount -> SelectedCount -> IO ()
$cpoke :: Ptr SelectedCount -> SelectedCount -> IO ()
peek :: Ptr SelectedCount -> IO SelectedCount
$cpeek :: Ptr SelectedCount -> IO SelectedCount
pokeByteOff :: Ptr b -> Int -> SelectedCount -> IO ()
$cpokeByteOff :: forall b. Ptr b -> Int -> SelectedCount -> IO ()
peekByteOff :: Ptr b -> Int -> IO SelectedCount
$cpeekByteOff :: forall b. Ptr b -> Int -> IO SelectedCount
pokeElemOff :: Ptr SelectedCount -> Int -> SelectedCount -> IO ()
$cpokeElemOff :: Ptr SelectedCount -> Int -> SelectedCount -> IO ()
peekElemOff :: Ptr SelectedCount -> Int -> IO SelectedCount
$cpeekElemOff :: Ptr SelectedCount -> Int -> IO SelectedCount
alignment :: SelectedCount -> Int
$calignment :: SelectedCount -> Int
sizeOf :: SelectedCount -> Int
$csizeOf :: SelectedCount -> Int
Storable, Typeable SelectedCount
DataType
Constr
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 -> DataType
SelectedCount -> Constr
(forall b. Data b => b -> b) -> SelectedCount -> SelectedCount
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SelectedCount -> c SelectedCount
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c 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)
$cSelectedCount :: Constr
$tSelectedCount :: DataType
gmapMo :: (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
gmapMp :: (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
gmapM :: (forall d. Data d => d -> m d) -> SelectedCount -> m SelectedCount
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SelectedCount -> m SelectedCount
gmapQi :: Int -> (forall d. Data d => d -> u) -> SelectedCount -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> SelectedCount -> u
gmapQ :: (forall d. Data d => d -> u) -> SelectedCount -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> SelectedCount -> [u]
gmapQr :: (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
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SelectedCount -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SelectedCount -> r
gmapT :: (forall b. Data b => b -> b) -> SelectedCount -> SelectedCount
$cgmapT :: (forall b. Data b => b -> b) -> SelectedCount -> SelectedCount
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SelectedCount)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c SelectedCount)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c SelectedCount)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SelectedCount)
dataTypeOf :: SelectedCount -> DataType
$cdataTypeOf :: SelectedCount -> DataType
toConstr :: SelectedCount -> Constr
$ctoConstr :: SelectedCount -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SelectedCount
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SelectedCount
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SelectedCount -> c SelectedCount
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SelectedCount -> c SelectedCount
$cp1Data :: Typeable 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 (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 (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 (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 :: 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 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 k (t :: k) (m :: * -> *) a.
MonadSample t m =>
Behavior t a -> m a
sample (Dynamic t q -> Behavior t q
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 k (t :: k) a. Reflex t => Dynamic t a -> Behavior t a
current Dynamic t q
d) (Dynamic t q -> Event t q
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 :: 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 :: 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 (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 (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap q1 -> q2
f Dynamic t q1
x)