@@ -46,6 +46,21 @@ catMaybeTable ma@(MaybeTable _ a) = do
49+-- | @bindMaybeTable f x@ is similar to the monadic bind (@>>=@) operation. It
50+-- allows you to "extend" an optional query with another query. If either the
51+-- input or output are 'noTable', then the result is 'noTable'.
53+-- This is similar to 'traverseMaybeTable', followed by a @join@ on the
54+-- resulting @MaybeTable@s.
56+-- >>> select c $ bindMaybeTable (optional . values . pure . not_) =<< optional (values [lit True])
59+-- >>> select c $ bindMaybeTable (\_ -> return (noTable :: MaybeTable (Expr Bool))) =<< optional (values [lit True])
62+-- >>> select c $ bindMaybeTable (optional . values . pure . not_) =<< return (noTable :: MaybeTable (Expr Bool))
49bindMaybeTable :: Monad m
64bindMaybeTable :: Monad m
50 => (a -> m (MaybeTable b)) -> MaybeTable a -> m (MaybeTable b)
65 => (a -> m (MaybeTable b)) -> MaybeTable a -> m (MaybeTable b)
51bindMaybeTable query (MaybeTable input a) = do
66bindMaybeTable query (MaybeTable input a) = do
@@ -53,6 +68,34 @@ bindMaybeTable query (MaybeTable input a) = do
53 pure $ MaybeTable (input <> output) b
68 pure $ MaybeTable (input <> output) b
71+-- | Extend an optional query with another query. This is useful if you want
72+-- to step through multiple @LEFT JOINs@.
74+-- Note that @traverseMaybeTable@ takes a @a -> Query b@ function, which means
75+-- you also have the ability to "expand" one row into multiple rows.
78+-- duplicate :: Expr Bool -> Query (Expr Bool)
79+-- duplicate x = unionAll (return x) (return x)
82+-- >>> select c $ traverseMaybeTable duplicate =<< optional (values [lit True])
83+-- [Just True,Just True]
85+-- Note that if the @a -> Query b@ function returns no rows, then the resulting
86+-- query will also have no rows:
88+-- >>> select c $ traverseMaybeTable (limit 0 . pure) =<< optional (values [lit True])
91+-- However, regardless of the given @a -> Query b@ function, if the input is
92+-- @noTable@, you will always get exactly one @noTable@ back:
94+-- >>> select c $ traverseMaybeTable duplicate (noTable :: MaybeTable (Expr Bool))
97+-- >>> select c $ traverseMaybeTable (limit 0 . pure) (noTable :: MaybeTable (Expr Bool))
56traverseMaybeTable :: (a -> Query b) -> MaybeTable a -> Query (MaybeTable b)
99traverseMaybeTable :: (a -> Query b) -> MaybeTable a -> Query (MaybeTable b)
57traverseMaybeTable query ma@(MaybeTable input _) = do
100traverseMaybeTable query ma@(MaybeTable input _) = do
58 MaybeTable output b <- optional (query =<< catMaybeTable ma)
101 MaybeTable output b <- optional (query =<< catMaybeTable ma)