@@ -28,6 +28,9 @@ import Rel8.Type ( DBType, typeInformation )
2828import Rel8.Type.Information ( TypeInformation )
2929
3030
31+-- | Lift an expression that can't be @null@ to a type that might be @null@.
32+-- This is an identity operation in terms of any generated query, and just
33+-- modifies the query's type.
3134nullify :: IsMaybe a ~ 'False => Expr a -> Expr (Maybe a)
3235nullify (Expr a) = Expr a
3336
@@ -36,6 +39,13 @@ unsafeUnnullify :: Expr (Maybe a) -> Expr a
3639unsafeUnnullify (Expr a) = Expr a
3740
3841
42+-- | Like 'maybe', but to eliminate @null@.
43+--
44+-- >>> select c $ pure $ null 0 id (nullExpr :: Expr (Maybe Int32))
45+-- [0]
46+--
47+-- >>> select c $ pure $ null 0 id (lit (Just 42) :: Expr (Maybe Int32))
48+-- [42]
3949nullable :: Expr b -> (Expr a -> Expr b) -> Expr (Maybe a) -> Expr b
4050nullable b f ma = boolExpr (f (unsafeUnnullify ma)) b (isNull ma)
4151
@@ -45,19 +55,36 @@ nullableOf :: (IsMaybe a ~ 'False, DBType a)
4555nullableOf = maybe null nullify
4656
4757
58+-- | Like 'isNothing', but for @null@.
59+--
60+-- >>> select c $ pure $ isNull (nullExpr :: Expr (Maybe Int32))
61+-- [True]
62+--
63+-- >>> select c $ pure $ isNull (lit (Just 42) :: Expr (Maybe Int32))
64+-- [False]
4865isNull :: Expr (Maybe a) -> Expr Bool
4966isNull = mapPrimExpr (Opaleye.UnExpr Opaleye.OpIsNull)
5067
5168
69+-- | Like 'isJust', but for @null@.
5270isNonNull :: Expr (Maybe a) -> Expr Bool
5371isNonNull = mapPrimExpr (Opaleye.UnExpr Opaleye.OpIsNotNull)
5472
5573
74+-- | Lift an operation on non-@null@ values to an operation on possibly @null@
75+-- values. When given @null@, @mapNullable f@ returns @null@.
76+--
77+-- This is like 'fmap' for 'Maybe'.
5678mapNullable :: (IsMaybe b ~ 'False, DBType b)
5779 => (Expr a -> Expr b) -> Expr (Maybe a) -> Expr (Maybe b)
5880mapNullable f ma = boolExpr (unsafeMapNullable f ma) null (isNull ma)
5981
6082
83+-- | Lift a binary operation on non-@null@ expressions to an equivalent binary
84+-- operator on possibly @null@ expressions. If either of the final arguments
85+-- are @null@, @liftOpNullable@ returns @null@.
86+--
87+-- This is like 'liftA2' for 'Maybe'.
6188liftOpNullable :: (IsMaybe c ~ 'False, DBType c)
6289 => (Expr a -> Expr b -> Expr c)
6390 -> Expr (Maybe a) -> Expr (Maybe b) -> Expr (Maybe c)
@@ -71,6 +98,7 @@ snull nullability info =
7198 scastExpr nullability info $ Expr $ Opaleye.ConstExpr Opaleye.NullLit
7299
73100
101+-- | Corresponds to SQL @null@.
74102null :: (IsMaybe a ~ 'False, DBType a) => Expr (Maybe a)
75103null = snull Nullable typeInformation
76104