{-# language DataKinds #-}
{-# language OverloadedStrings #-}

module Rel8.Expr.Text
  (
    -- * String concatenation
    (++.)

    -- * Regular expression operators
  , (~.), (~*), (!~), (!~*)

    -- * Standard SQL functions
  , bitLength, charLength, lower, octetLength, upper

    -- * PostgreSQL functions
  , ascii, btrim, chr, convert, convertFrom, convertTo, decode, encode
  , initcap, left, length, lengthEncoding, lpad, ltrim, md5
  , pgClientEncoding, quoteIdent, quoteLiteral, quoteNullable, regexpReplace
  , regexpSplitToArray, repeat, replace, reverse, right, rpad, rtrim
  , splitPart, strpos, substr, translate

    -- * @LIKE@ and @ILIKE@
  , like, ilike
  )
where

-- base
import Data.Bool ( Bool )
import Data.Int ( Int32 )
import Data.Maybe ( Maybe( Nothing, Just ) )
import Prelude ( flip )

-- bytestring
import Data.ByteString ( ByteString )

-- opaleye
import qualified Opaleye.Internal.HaskellDB.PrimQuery as Opaleye

-- rel8
import Rel8.Expr ( Expr )
import Rel8.Expr.Function (binaryOperator, function)
import Rel8.Expr.Opaleye (zipPrimExprsWith)

-- text
import Data.Text (Text)


-- | The PostgreSQL string concatenation operator.
(++.) :: Expr Text -> Expr Text -> Expr Text
++. :: Expr Text -> Expr Text -> Expr Text
(++.) = QualifiedName -> Expr Text -> Expr Text -> Expr Text
forall c a b.
Sql DBType c =>
QualifiedName -> Expr a -> Expr b -> Expr c
binaryOperator QualifiedName
"||"
infixr 6 ++.


-- * Regular expression operators

-- See https://www.postgresql.org/docs/9.5/static/functions-matching.html#FUNCTIONS-POSIX-REGEXP


-- | Matches regular expression, case sensitive
--
-- Corresponds to the @~.@ operator.
(~.) :: Expr Text -> Expr Text -> Expr Bool
~. :: Expr Text -> Expr Text -> Expr Bool
(~.) = QualifiedName -> Expr Text -> Expr Text -> Expr Bool
forall c a b.
Sql DBType c =>
QualifiedName -> Expr a -> Expr b -> Expr c
binaryOperator QualifiedName
"~."
infix 2 ~.


-- | Matches regular expression, case insensitive
--
-- Corresponds to the @~*@ operator.
(~*) :: Expr Text -> Expr Text -> Expr Bool
~* :: Expr Text -> Expr Text -> Expr Bool
(~*) = QualifiedName -> Expr Text -> Expr Text -> Expr Bool
forall c a b.
Sql DBType c =>
QualifiedName -> Expr a -> Expr b -> Expr c
binaryOperator QualifiedName
"~*"
infix 2 ~*


-- | Does not match regular expression, case sensitive
--
-- Corresponds to the @!~@ operator.
(!~) :: Expr Text -> Expr Text -> Expr Bool
!~ :: Expr Text -> Expr Text -> Expr Bool
(!~) = QualifiedName -> Expr Text -> Expr Text -> Expr Bool
forall c a b.
Sql DBType c =>
QualifiedName -> Expr a -> Expr b -> Expr c
binaryOperator QualifiedName
"!~"
infix 2 !~


-- | Does not match regular expression, case insensitive
--
-- Corresponds to the @!~*@ operator.
(!~*) :: Expr Text -> Expr Text -> Expr Bool
!~* :: Expr Text -> Expr Text -> Expr Bool
(!~*) = QualifiedName -> Expr Text -> Expr Text -> Expr Bool
forall c a b.
Sql DBType c =>
QualifiedName -> Expr a -> Expr b -> Expr c
binaryOperator QualifiedName
"!~*"
infix 2 !~*


-- See https://www.postgresql.org/docs/9.5/static/functions-Expr.'PGHtml

-- * Standard SQL functions


-- | Corresponds to the @bit_length@ function.
bitLength :: Expr Text -> Expr Int32
bitLength :: Expr Text -> Expr Int32
bitLength = QualifiedName -> Expr Text -> Expr Int32
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"bit_length"


-- | Corresponds to the @char_length@ function.
charLength :: Expr Text -> Expr Int32
charLength :: Expr Text -> Expr Int32
charLength = QualifiedName -> Expr Text -> Expr Int32
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"char_length"


-- | Corresponds to the @lower@ function.
lower :: Expr Text -> Expr Text
lower :: Expr Text -> Expr Text
lower = QualifiedName -> Expr Text -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"lower"


-- | Corresponds to the @octet_length@ function.
octetLength :: Expr Text -> Expr Int32
octetLength :: Expr Text -> Expr Int32
octetLength = QualifiedName -> Expr Text -> Expr Int32
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"octet_length"


-- | Corresponds to the @upper@ function.
upper :: Expr Text -> Expr Text
upper :: Expr Text -> Expr Text
upper = QualifiedName -> Expr Text -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"upper"


-- | Corresponds to the @ascii@ function.
ascii :: Expr Text -> Expr Int32
ascii :: Expr Text -> Expr Int32
ascii = QualifiedName -> Expr Text -> Expr Int32
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"ascii"


-- | Corresponds to the @btrim@ function.
btrim :: Expr Text -> Maybe (Expr Text) -> Expr Text
btrim :: Expr Text -> Maybe (Expr Text) -> Expr Text
btrim Expr Text
a (Just Expr Text
b) = QualifiedName -> (Expr Text, Expr Text) -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"btrim" (Expr Text
a, Expr Text
b)
btrim Expr Text
a Maybe (Expr Text)
Nothing = QualifiedName -> Expr Text -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"btrim" Expr Text
a


-- | Corresponds to the @chr@ function.
chr :: Expr Int32 -> Expr Text
chr :: Expr Int32 -> Expr Text
chr = QualifiedName -> Expr Int32 -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"chr"


-- | Corresponds to the @convert@ function.
convert :: Expr ByteString -> Expr Text -> Expr Text -> Expr ByteString
convert :: Expr ByteString -> Expr Text -> Expr Text -> Expr ByteString
convert Expr ByteString
a Expr Text
b Expr Text
c = QualifiedName
-> (Expr ByteString, Expr Text, Expr Text) -> Expr ByteString
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"convert" (Expr ByteString
a, Expr Text
b, Expr Text
c)


-- | Corresponds to the @convert_from@ function.
convertFrom :: Expr ByteString -> Expr Text -> Expr Text
convertFrom :: Expr ByteString -> Expr Text -> Expr Text
convertFrom Expr ByteString
a Expr Text
b = QualifiedName -> (Expr ByteString, Expr Text) -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"convert_from" (Expr ByteString
a, Expr Text
b)


-- | Corresponds to the @convert_to@ function.
convertTo :: Expr Text -> Expr Text -> Expr ByteString
convertTo :: Expr Text -> Expr Text -> Expr ByteString
convertTo Expr Text
a Expr Text
b = QualifiedName -> (Expr Text, Expr Text) -> Expr ByteString
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"convert_to" (Expr Text
a, Expr Text
b)


-- | Corresponds to the @decode@ function.
decode :: Expr Text -> Expr Text -> Expr ByteString
decode :: Expr Text -> Expr Text -> Expr ByteString
decode Expr Text
a Expr Text
b = QualifiedName -> (Expr Text, Expr Text) -> Expr ByteString
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"decode" (Expr Text
a, Expr Text
b)


-- | Corresponds to the @encode@ function.
encode :: Expr ByteString -> Expr Text -> Expr Text
encode :: Expr ByteString -> Expr Text -> Expr Text
encode Expr ByteString
a Expr Text
b = QualifiedName -> (Expr ByteString, Expr Text) -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"encode" (Expr ByteString
a, Expr Text
b)


-- | Corresponds to the @initcap@ function.
initcap :: Expr Text -> Expr Text
initcap :: Expr Text -> Expr Text
initcap = QualifiedName -> Expr Text -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"initcap"


-- | Corresponds to the @left@ function.
left :: Expr Text -> Expr Int32 -> Expr Text
left :: Expr Text -> Expr Int32 -> Expr Text
left Expr Text
a Expr Int32
b = QualifiedName -> (Expr Text, Expr Int32) -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"left" (Expr Text
a, Expr Int32
b)


-- | Corresponds to the @length@ function.
length :: Expr Text -> Expr Int32
length :: Expr Text -> Expr Int32
length = QualifiedName -> Expr Text -> Expr Int32
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"length"


-- | Corresponds to the @length@ function.
lengthEncoding :: Expr ByteString -> Expr Text -> Expr Int32
lengthEncoding :: Expr ByteString -> Expr Text -> Expr Int32
lengthEncoding Expr ByteString
a Expr Text
b = QualifiedName -> (Expr ByteString, Expr Text) -> Expr Int32
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"length" (Expr ByteString
a, Expr Text
b)


-- | Corresponds to the @lpad@ function.
lpad :: Expr Text -> Expr Int32 -> Maybe (Expr Text) -> Expr Text
lpad :: Expr Text -> Expr Int32 -> Maybe (Expr Text) -> Expr Text
lpad Expr Text
a Expr Int32
b (Just Expr Text
c) = QualifiedName -> (Expr Text, Expr Int32, Expr Text) -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"lpad" (Expr Text
a, Expr Int32
b, Expr Text
c)
lpad Expr Text
a Expr Int32
b Maybe (Expr Text)
Nothing = QualifiedName -> (Expr Text, Expr Int32) -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"lpad" (Expr Text
a, Expr Int32
b)


-- | Corresponds to the @ltrim@ function.
ltrim :: Expr Text -> Maybe (Expr Text) -> Expr Text
ltrim :: Expr Text -> Maybe (Expr Text) -> Expr Text
ltrim Expr Text
a (Just Expr Text
b) = QualifiedName -> (Expr Text, Expr Text) -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"ltrim" (Expr Text
a, Expr Text
b)
ltrim Expr Text
a Maybe (Expr Text)
Nothing = QualifiedName -> Expr Text -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"ltrim" Expr Text
a


-- | Corresponds to the @md5@ function.
md5 :: Expr Text -> Expr Text
md5 :: Expr Text -> Expr Text
md5 = QualifiedName -> Expr Text -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"md5"


-- | Corresponds to the @pg_client_encoding()@ expression.
pgClientEncoding :: Expr Text
pgClientEncoding :: Expr Text
pgClientEncoding = QualifiedName -> () -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"pg_client_encoding" ()


-- | Corresponds to the @quote_ident@ function.
quoteIdent :: Expr Text -> Expr Text
quoteIdent :: Expr Text -> Expr Text
quoteIdent = QualifiedName -> Expr Text -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"quote_ident"


-- | Corresponds to the @quote_literal@ function.
quoteLiteral :: Expr Text -> Expr Text
quoteLiteral :: Expr Text -> Expr Text
quoteLiteral = QualifiedName -> Expr Text -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"quote_literal"


-- | Corresponds to the @quote_nullable@ function.
quoteNullable :: Expr Text -> Expr Text
quoteNullable :: Expr Text -> Expr Text
quoteNullable = QualifiedName -> Expr Text -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"quote_nullable"


-- | Corresponds to the @regexp_replace@ function.
regexpReplace :: ()
  => Expr Text -> Expr Text -> Expr Text -> Maybe (Expr Text) -> Expr Text
regexpReplace :: Expr Text
-> Expr Text -> Expr Text -> Maybe (Expr Text) -> Expr Text
regexpReplace Expr Text
a Expr Text
b Expr Text
c (Just Expr Text
d) = QualifiedName
-> (Expr Text, Expr Text, Expr Text, Expr Text) -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"regexp_replace" (Expr Text
a, Expr Text
b, Expr Text
c, Expr Text
d)
regexpReplace Expr Text
a Expr Text
b Expr Text
c Maybe (Expr Text)
Nothing = QualifiedName -> (Expr Text, Expr Text, Expr Text) -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"regexp_replace" (Expr Text
a, Expr Text
b, Expr Text
c)


-- | Corresponds to the @regexp_split_to_array@ function.
regexpSplitToArray :: ()
  => Expr Text -> Expr Text -> Maybe (Expr Text) -> Expr [Text]
regexpSplitToArray :: Expr Text -> Expr Text -> Maybe (Expr Text) -> Expr [Text]
regexpSplitToArray Expr Text
a Expr Text
b (Just Expr Text
c) = QualifiedName -> (Expr Text, Expr Text, Expr Text) -> Expr [Text]
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"regexp_split_to_array" (Expr Text
a, Expr Text
b, Expr Text
c)
regexpSplitToArray Expr Text
a Expr Text
b Maybe (Expr Text)
Nothing = QualifiedName -> (Expr Text, Expr Text) -> Expr [Text]
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"regexp_split_to_array" (Expr Text
a, Expr Text
b)


-- | Corresponds to the @repeat@ function.
repeat :: Expr Text -> Expr Int32 -> Expr Text
repeat :: Expr Text -> Expr Int32 -> Expr Text
repeat Expr Text
a Expr Int32
b = QualifiedName -> (Expr Text, Expr Int32) -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"repeat" (Expr Text
a, Expr Int32
b)


-- | Corresponds to the @replace@ function.
replace :: Expr Text -> Expr Text -> Expr Text -> Expr Text
replace :: Expr Text -> Expr Text -> Expr Text -> Expr Text
replace Expr Text
a Expr Text
b Expr Text
c = QualifiedName -> (Expr Text, Expr Text, Expr Text) -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"replace" (Expr Text
a, Expr Text
b, Expr Text
c)


-- | Corresponds to the @reverse@ function.
reverse :: Expr Text -> Expr Text
reverse :: Expr Text -> Expr Text
reverse = QualifiedName -> Expr Text -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"reverse"


-- | Corresponds to the @right@ function.
right :: Expr Text -> Expr Int32 -> Expr Text
right :: Expr Text -> Expr Int32 -> Expr Text
right Expr Text
a Expr Int32
b = QualifiedName -> (Expr Text, Expr Int32) -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"right" (Expr Text
a, Expr Int32
b)


-- | Corresponds to the @rpad@ function.
rpad :: Expr Text -> Expr Int32 -> Maybe (Expr Text) -> Expr Text
rpad :: Expr Text -> Expr Int32 -> Maybe (Expr Text) -> Expr Text
rpad Expr Text
a Expr Int32
b (Just Expr Text
c) = QualifiedName -> (Expr Text, Expr Int32, Expr Text) -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"rpad" (Expr Text
a, Expr Int32
b, Expr Text
c)
rpad Expr Text
a Expr Int32
b Maybe (Expr Text)
Nothing = QualifiedName -> (Expr Text, Expr Int32) -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"rpad" (Expr Text
a, Expr Int32
b)


-- | Corresponds to the @rtrim@ function.
rtrim :: Expr Text -> Maybe (Expr Text) -> Expr Text
rtrim :: Expr Text -> Maybe (Expr Text) -> Expr Text
rtrim Expr Text
a (Just Expr Text
b) = QualifiedName -> (Expr Text, Expr Text) -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"rtrim" (Expr Text
a, Expr Text
b)
rtrim Expr Text
a Maybe (Expr Text)
Nothing = QualifiedName -> Expr Text -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"rtrim" Expr Text
a


-- | Corresponds to the @split_part@ function.
splitPart :: Expr Text -> Expr Text -> Expr Int32 -> Expr Text
splitPart :: Expr Text -> Expr Text -> Expr Int32 -> Expr Text
splitPart Expr Text
a Expr Text
b Expr Int32
c = QualifiedName -> (Expr Text, Expr Text, Expr Int32) -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"split_part" (Expr Text
a, Expr Text
b, Expr Int32
c)


-- | Corresponds to the @strpos@ function.
strpos :: Expr Text -> Expr Text -> Expr Int32
strpos :: Expr Text -> Expr Text -> Expr Int32
strpos Expr Text
a Expr Text
b = QualifiedName -> (Expr Text, Expr Text) -> Expr Int32
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"strpos" (Expr Text
a, Expr Text
b)


-- | Corresponds to the @substr@ function.
substr :: Expr Text -> Expr Int32 -> Maybe (Expr Int32) -> Expr Text
substr :: Expr Text -> Expr Int32 -> Maybe (Expr Int32) -> Expr Text
substr Expr Text
a Expr Int32
b (Just Expr Int32
c) = QualifiedName -> (Expr Text, Expr Int32, Expr Int32) -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"substr" (Expr Text
a, Expr Int32
b, Expr Int32
c)
substr Expr Text
a Expr Int32
b Maybe (Expr Int32)
Nothing = QualifiedName -> (Expr Text, Expr Int32) -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"substr" (Expr Text
a, Expr Int32
b)


-- | Corresponds to the @translate@ function.
translate :: Expr Text -> Expr Text -> Expr Text -> Expr Text
translate :: Expr Text -> Expr Text -> Expr Text -> Expr Text
translate Expr Text
a Expr Text
b Expr Text
c = QualifiedName -> (Expr Text, Expr Text, Expr Text) -> Expr Text
forall arguments a.
(Arguments arguments, Sql DBType a) =>
QualifiedName -> arguments -> Expr a
function QualifiedName
"translate" (Expr Text
a, Expr Text
b, Expr Text
c)


-- | @like x y@ corresponds to the expression @y LIKE x@.
--
-- Note that the arguments to @like@ are swapped. This is to aid currying, so
-- you can write expressions like
-- @filter (like "Rel%" . packageName) =<< each haskellPackages@
like :: Expr Text -> Expr Text -> Expr Bool
like :: Expr Text -> Expr Text -> Expr Bool
like = (Expr Text -> Expr Text -> Expr Bool)
-> Expr Text -> Expr Text -> Expr Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((PrimExpr -> PrimExpr -> PrimExpr)
-> Expr Text -> Expr Text -> Expr Bool
forall a b c.
(PrimExpr -> PrimExpr -> PrimExpr) -> Expr a -> Expr b -> Expr c
zipPrimExprsWith (BinOp -> PrimExpr -> PrimExpr -> PrimExpr
Opaleye.BinExpr BinOp
Opaleye.OpLike))


-- | @ilike x y@ corresponds to the expression @y ILIKE x@.
--
-- Note that the arguments to @ilike@ are swapped. This is to aid currying, so
-- you can write expressions like
-- @filter (ilike "Rel%" . packageName) =<< each haskellPackages@
ilike :: Expr Text -> Expr Text -> Expr Bool
ilike :: Expr Text -> Expr Text -> Expr Bool
ilike = (Expr Text -> Expr Text -> Expr Bool)
-> Expr Text -> Expr Text -> Expr Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((PrimExpr -> PrimExpr -> PrimExpr)
-> Expr Text -> Expr Text -> Expr Bool
forall a b c.
(PrimExpr -> PrimExpr -> PrimExpr) -> Expr a -> Expr b -> Expr c
zipPrimExprsWith (BinOp -> PrimExpr -> PrimExpr -> PrimExpr
Opaleye.BinExpr BinOp
Opaleye.OpILike))