@@ -295,33 +295,45 @@ newtype Expression
295295instance RenderSQL (Expression outer grp commons schemas params from ty) where
296296 renderSQL = renderExpression
297297
298+-- | An `Expr` is a closed `Expression`.
298299type Expr x
299300 = forall outer grp commons schemas params from
300301 . Expression outer grp commons schemas params from x
302+ -- ^ cannot reference aliases
301303
302304type Operator x1 x2 y
303305 = forall outer grp commons schemas params from
304306 . Expression outer grp commons schemas params from x1
307+ -- ^ left input
305308 -> Expression outer grp commons schemas params from x2
309+ -- ^ right input
306310 -> Expression outer grp commons schemas params from y
311+ -- ^ output
307312
308313type (:-->) x y
309314 = forall outer grp commons schemas params from
310315 . Expression outer grp commons schemas params from x
316+ -- ^ input
311317 -> Expression outer grp commons schemas params from y
318+ -- ^ output
312319
313320type FunctionHet xs y
314321 = forall outer grp commons schemas params from
315322 . NP (Expression outer grp commons schemas params from) xs
323+ -- ^ inputs
316324 -> Expression outer grp commons schemas params from y
325+ -- ^ output
317326
318−type FunctionHom x y
327+type FunctionHom x0 x1 y
319328 = forall outer grp commons schemas params from
320− . [Expression outer grp commons schemas params from x]
321− -> Expression outer grp commons schemas params from x
329+ . [Expression outer grp commons schemas params from x0]
330+ -- ^ inputs
331+ -> Expression outer grp commons schemas params from x1
332+ -- ^ must have at least 1 input
322333 -> Expression outer grp commons schemas params from y
334+ -- ^ output
323335
324−unsafeFunctionHom :: ByteString -> FunctionHom x y
336+unsafeFunctionHom :: ByteString -> FunctionHom x0 x1 y
325337unsafeFunctionHom fun xs x = UnsafeExpression $ fun <> parenthesized
326338 (commaSeparated (renderSQL <$> xs) <> ", " <> renderSQL x)
327339
@@ -479,12 +491,7 @@ notNull = UnsafeExpression . renderSQL
479491--
480492-- >>> printSQL $ coalesce [null_, true] false
481493-- COALESCE(NULL, TRUE, FALSE)
482−coalesce
483− :: [Expression outer grp commons schemas params from ('Null ty)]
484− -- ^ @NULL@s may be present
485− -> Expression outer grp commons schemas params from ('NotNull ty)
486− -- ^ @NULL@ is absent
487− -> Expression outer grp commons schemas params from ('NotNull ty)
494+coalesce :: FunctionHom ('Null ty) ('NotNull ty) ('NotNull ty)
488495coalesce nullxs notNullx = UnsafeExpression $
489496 "COALESCE" <> parenthesized (commaSeparated
490497 ((renderSQL <$> nullxs) <> [renderSQL notNullx]))
@@ -502,18 +509,12 @@ fromNull notNullx nullx = coalesce [nullx] notNullx
502509
503510-- | >>> printSQL $ null_ & isNull
504511-- NULL IS NULL
505−isNull
506− :: Expression outer grp commons schemas params from ('Null ty)
507− -- ^ possibly @NULL@
508− -> Condition outer grp commons schemas params from
512+isNull :: 'Null ty :--> null 'PGbool
509513isNull x = UnsafeExpression $ renderSQL x <+> "IS NULL"
510514
511515-- | >>> printSQL $ null_ & isNotNull
512516-- NULL IS NOT NULL
513−isNotNull
514− :: Expression outer grp commons schemas params from ('Null ty)
515− -- ^ possibly @NULL@
516− -> Condition outer grp commons schemas params from
517+isNotNull :: 'Null ty :--> null 'PGbool
517518isNotNull x = UnsafeExpression $ renderSQL x <+> "IS NOT NULL"
518519
519520-- | analagous to `maybe` using @IS NULL@
@@ -535,18 +536,12 @@ matchNull y f x = ifThenElse (isNull x) y
535536`nullIf` gives @NULL@.
536537
537538>>> :set -XTypeApplications -XDataKinds
538−>>> let expr = nullIf false (param @1) :: Expression outer grp commons schemas '[ 'NotNull 'PGbool] from ('Null 'PGbool)
539+>>> let expr = nullIf (false *: param @1) :: Expression outer grp commons schemas '[ 'NotNull 'PGbool] from ('Null 'PGbool)
539540>>> printSQL expr
540−NULL IF (FALSE, ($1 :: bool))
541+NULLIF(FALSE, ($1 :: bool))
541542-}
542−nullIf
543− :: Expression outer grp commons schemas params from ('NotNull ty)
544− -- ^ @NULL@ is absent
545− -> Expression outer grp commons schemas params from ('NotNull ty)
546− -- ^ @NULL@ is absent
547− -> Expression outer grp commons schemas params from ('Null ty)
548−nullIf x y = UnsafeExpression $ "NULL IF" <+> parenthesized
549− (renderSQL x <> ", " <> renderSQL y)
543+nullIf :: FunctionHet '[ 'NotNull ty, 'NotNull ty] ('Null ty)
544+nullIf = functionHet "NULLIF"
550545
551546-- | >>> printSQL $ array [null_, false, true]
552547-- ARRAY[NULL, FALSE, TRUE]
@@ -628,12 +623,12 @@ instance Monoid
628623-- | >>> let expr = greatest [param @1] currentTimestamp :: Expression outer grp commons schemas '[ 'NotNull 'PGtimestamptz] from ('NotNull 'PGtimestamptz)
629624-- >>> printSQL expr
630625-- GREATEST(($1 :: timestamp with time zone), CURRENT_TIMESTAMP)
631−greatest :: FunctionHom ty ty
626+greatest :: FunctionHom ty ty ty
632627greatest = unsafeFunctionHom "GREATEST"
633628
634629-- | >>> printSQL $ least [null_] currentTimestamp
635630-- LEAST(NULL, CURRENT_TIMESTAMP)
636−least :: FunctionHom ty ty
631+least :: FunctionHom ty ty ty
637632least = unsafeFunctionHom "LEAST"
638633
639634-- | >>> printSQL $ unsafeBinaryOp "OR" true false