1{-# language DeriveFunctor #-}
2{-# language DerivingStrategies #-}
3{-# language FlexibleContexts #-}
4{-# language TupleSections #-}
32import Control.Applicative ( liftA2 )
33import Control.Monad ( join, liftM2 )
34import Data.Bifunctor ( bimap, first )
35import Data.Foldable ( traverse_ )
36import Data.Maybe ( fromMaybe )
37import Prelude hiding ( filter, lookup, undefined, zip, zipWith )
40import Rel8.Aggregate ( Aggregate )
41import Rel8.Expr ( Expr )
42import Rel8.Expr.Bool ( not_, true )
43import Rel8.Query ( Query )
44import Rel8.Query.Aggregate ( aggregate )
45import Rel8.Query.Exists ( withBy, withoutBy )
46import Rel8.Query.Filter ( filter, where_ )
47import Rel8.Query.Maybe ( optional )
48import Rel8.Query.These ( alignBy )
49import Rel8.Table ( Table )
50import Rel8.Table.Aggregate ( groupBy )
51import Rel8.Table.Eq ( EqTable, (==:) )
52import Rel8.Table.Maybe ( MaybeTable )
53import Rel8.Table.These ( TheseTable, theseTable )
54import Rel8.Table.Undefined ( undefined )
57import Data.Functor.Apply ( Apply, liftF2 )
58import Data.Functor.Bind ( Bind )
59import qualified Data.Functor.Bind
60import Data.Semigroup.Traversable.Class ( bitraverse1 )
63newtype Tabulation k a = Tabulation (k -> Query (Maybe k, a))
64 deriving stock Functor
67instance EqTable k => Apply (Tabulation k) where
71instance EqTable k => Applicative (Tabulation k) where
72 pure = liftQuery . pure
76instance EqTable k => Bind (Tabulation k) where
80instance EqTable k => Monad (Tabulation k) where
81 Tabulation as >>= f = Tabulation $ \i -> do
84 Nothing -> case f a of
90 Nothing -> pure (mk, b)
96runTabulation :: EqTable k => Tabulation k a -> Query (k, a)
97runTabulation (Tabulation f) = do
101 -- Opaleye tries to be too clever optimising "WHERE FALSE" and generates
102 -- invalid SQL, so we use "WHERE NOT TRUE" instead
105 Just k -> pure (k, a)
110liftQuery :: Query a -> Tabulation k a
111liftQuery query = Tabulation $ const $ fmap (Nothing,) query
114tabulate :: (a -> k) -> a -> Tabulation k a
115tabulate key a = fromQuery $ pure (key a, a)
118tabulateA :: (a -> Query k) -> a -> Tabulation k a
119tabulateA key a = fromQuery $ (,a) <$> key a
122fromQuery :: Query (k, a) -> Tabulation k a
123fromQuery = Tabulation . const . fmap (first Just)
126indexed :: Tabulation k a -> Tabulation k (k, a)
127indexed (Tabulation query) = Tabulation $ \i ->
128 (\(mk, a) -> (mk, (fromMaybe i mk, a))) <$> query i
131ifilter :: (k -> a -> Expr Bool) -> Tabulation k a -> Tabulation k a
132ifilter f tabulation = snd <$> do
133 filter (uncurry f) `postbind` indexed tabulation
136prebind :: (a -> Tabulation k b) -> Query a -> Tabulation k b
137prebind f as = Tabulation $ \k -> do
140 Tabulation query -> query k
144postbind :: (a -> Query b) -> Tabulation k a -> Tabulation k b
145postbind f (Tabulation as) = Tabulation $ \i -> do
154lookup :: EqTable k => k -> Tabulation k a -> Query a
155lookup key (Tabulation query) = do
157 traverse_ (where_ . (key ==:)) mk
161align :: (EqTable k, Table Expr a, Table Expr b)
162 => Tabulation k a -> Tabulation k b -> Tabulation k (TheseTable a b)
166alignWith :: (EqTable k, Table Expr a, Table Expr b)
167 => (TheseTable a b -> c)
168 -> Tabulation k a -> Tabulation k b -> Tabulation k c
169alignWith f kas kbs = do
173 tkab <- alignBy (\(l, _) (m, _) -> l ==: m) as bs
175 k' = theseTable fst fst (const fst) tkab
176 tab = bimap snd snd tkab
180leftAlign :: EqTable k
181 => Tabulation k a -> Tabulation k b -> Tabulation k (a, MaybeTable b)
182leftAlign = leftAlignWith (,)
185leftAlignWith :: EqTable k
186 => (a -> MaybeTable b -> c)
187 -> Tabulation k a -> Tabulation k b -> Tabulation k c
188leftAlignWith f left right = liftA2 f left (optionalTabulation right)
192 => Tabulation k a -> Tabulation k b -> Tabulation k (a, b)
197 => (a -> b -> c) -> Tabulation k a -> Tabulation k b -> Tabulation k c
201similarity :: EqTable k => Tabulation k a -> Tabulation k b -> Tabulation k a
202similarity kas kbs = do
205 fromQuery $ as >>= withBy (\(k, _) (l, _) -> k ==: l) bs
208difference :: EqTable k => Tabulation k a -> Tabulation k b -> Tabulation k a
209difference kas kbs = do
212 fromQuery $ as >>= withoutBy (\(k, _) (l, _) -> k ==: l) bs
215aggregateTabulation :: EqTable k
216 => Tabulation k (Aggregate a) -> Tabulation k a
217aggregateTabulation kas = do
219 fromQuery $ aggregate $ bitraverse1 groupBy id <$> as
222optionalTabulation :: EqTable k
223 => Tabulation k a -> Tabulation k (MaybeTable a)
224optionalTabulation as = Tabulation $ \k -> do
225 ma <- optional $ lookup k as
229toQuery :: Tabulation k a -> Tabulation k (Query (k, a))
230toQuery (Tabulation as) = Tabulation $ \k ->
231 pure (Nothing, first (fromMaybe k) <$> as k)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list