@@ -21,40 +21,96 @@ import Rel8.Expr.Opaleye ( mapPrimExpr, zipPrimExprsWith )
21import Rel8.Expr.Serialize ( litExpr )
21import Rel8.Expr.Serialize ( litExpr )
24+-- | The SQL @false@ literal.
24false :: Expr Bool
25false :: Expr Bool
25false = litExpr False
26false = litExpr False
29+-- | The SQL @true@ literal.
28true :: Expr Bool
30true :: Expr Bool
29true = litExpr True
31true = litExpr True
34+-- | The SQL @AND@ operator.
37+-- mapM_ print =<< select c do
38+-- x <- values [lit True, lit False]
39+-- y <- values [lit True, lit False]
40+-- return (x, y, x &&. y)
45+-- (False,False,False)
32(&&.) :: Expr Bool -> Expr Bool -> Expr Bool
46(&&.) :: Expr Bool -> Expr Bool -> Expr Bool
33(&&.) = zipPrimExprsWith (Opaleye.BinExpr Opaleye.OpAnd)
47(&&.) = zipPrimExprsWith (Opaleye.BinExpr Opaleye.OpAnd)
34infixr 3 &&.
48infixr 3 &&.
51+-- | The SQL @OR@ operator.
54+-- mapM_ print =<< select c do
55+-- x <- values [lit True, lit False]
56+-- y <- values [lit True, lit False]
57+-- return (x, y, x ||. y)
62+-- (False,False,False)
37(||.) :: Expr Bool -> Expr Bool -> Expr Bool
63(||.) :: Expr Bool -> Expr Bool -> Expr Bool
38(||.) = zipPrimExprsWith (Opaleye.BinExpr Opaleye.OpOr)
64(||.) = zipPrimExprsWith (Opaleye.BinExpr Opaleye.OpOr)
39infixr 2 ||.
65infixr 2 ||.
68+-- | The SQL @NOT@ operator.
70+-- >>> select c $ pure $ not_ $ lit True
73+-- >>> select c $ pure $ not_ $ lit False
42not_ :: Expr Bool -> Expr Bool
75not_ :: Expr Bool -> Expr Bool
43not_ = mapPrimExpr (Opaleye.UnExpr Opaleye.OpNot)
76not_ = mapPrimExpr (Opaleye.UnExpr Opaleye.OpNot)
79+-- | Fold @AND@ over a collection of expressions.
81+-- >>> select c $ pure $ and_ [ lit True ==. lit False, lit False, lit True ]
84+-- >>> select c $ pure $ and_ []
46and_ :: Foldable f => f (Expr Bool) -> Expr Bool
86and_ :: Foldable f => f (Expr Bool) -> Expr Bool
47and_ = foldl' (&&.) true
87and_ = foldl' (&&.) true
90+-- | Fold @OR@ over a collection of expressions.
92+-- >>> select c $ pure $ or_ [ lit True ==. lit False, lit False, lit True ]
95+-- >>> select c $ pure $ or_ []
50or_ :: Foldable f => f (Expr Bool) -> Expr Bool
97or_ :: Foldable f => f (Expr Bool) -> Expr Bool
51or_ = foldl' (||.) false
98or_ = foldl' (||.) false
101+-- | Eliminate a boolean-valued expression.
103+-- Corresponds to 'Data.Bool.bool'.
54boolExpr :: Expr a -> Expr a -> Expr Bool -> Expr a
104boolExpr :: Expr a -> Expr a -> Expr Bool -> Expr a
55boolExpr ifFalse ifTrue condition = caseExpr [(condition, ifTrue)] ifFalse
105boolExpr ifFalse ifTrue condition = caseExpr [(condition, ifTrue)] ifFalse
108+-- | A multi-way if/then/else statement. The first argument to @caseExpr@ is a
109+-- list of alternatives. The first alternative that is of the form @(true, x)@
110+-- will be returned. If no such alternative is found, a fallback expression is
113+-- Corresponds to a @CASE@ expression in SQL.
58caseExpr :: [(Expr Bool, Expr a)] -> Expr a -> Expr a
114caseExpr :: [(Expr Bool, Expr a)] -> Expr a -> Expr a
59caseExpr branches (Expr fallback) =
115caseExpr branches (Expr fallback) =
60 Expr $ Opaleye.CaseExpr (map go branches) fallback
116 Expr $ Opaleye.CaseExpr (map go branches) fallback