{-# OPTIONS_HADDOCK not-home #-}

{-# LANGUAGE Arrows #-}
{-# LANGUAGE TypeSynonymInstances #-}

module Opaleye.Internal.QueryArr where

import           Prelude hiding (id)

import qualified Opaleye.Internal.Unpackspec as U
import qualified Opaleye.Internal.Tag as Tag
import           Opaleye.Internal.Tag (Tag)
import qualified Opaleye.Internal.PrimQuery as PQ

import qualified Opaleye.Internal.HaskellDB.PrimQuery as HPQ

import qualified Control.Arrow as Arr
import           Control.Arrow ((&&&), (***), arr, returnA)
import qualified Control.Category as C
import           Control.Category ((<<<), id)
import           Control.Monad.Trans.State.Strict (State, evalState, runState, state)
import qualified Data.Profunctor as P
import qualified Data.Profunctor.Product as PP

-- | A parametrised 'Select'.  A @SelectArr a b@ accepts an argument
-- of type @a@.
--
-- @SelectArr a b@ is analogous to a Haskell function @a -> [b]@.
newtype SelectArr a b = QueryArr { forall a b. SelectArr a b -> a -> State Tag (b, PrimQueryArr)
unQueryArr :: a -> State Tag (b, PQ.PrimQueryArr) }

type QueryArr = SelectArr
type Query = SelectArr ()

selectArr :: State Tag (a -> (b, PQ.PrimQueryArr)) -> SelectArr a b
selectArr :: forall a b. State Tag (a -> (b, PrimQueryArr)) -> SelectArr a b
selectArr State Tag (a -> (b, PrimQueryArr))
s = (a -> State Tag (b, PrimQueryArr)) -> SelectArr a b
forall a b. (a -> State Tag (b, PrimQueryArr)) -> SelectArr a b
QueryArr (\a
a -> ((a -> (b, PrimQueryArr)) -> (b, PrimQueryArr))
-> State Tag (a -> (b, PrimQueryArr))
-> State Tag (b, PrimQueryArr)
forall a b.
(a -> b) -> StateT Tag Identity a -> StateT Tag Identity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> (b, PrimQueryArr)) -> a -> (b, PrimQueryArr)
forall a b. (a -> b) -> a -> b
$ a
a) State Tag (a -> (b, PrimQueryArr))
s)

productQueryArr :: State Tag (a, PQ.PrimQuery) -> Query a
productQueryArr :: forall a. State Tag (a, PrimQuery) -> Query a
productQueryArr State Tag (a, PrimQuery)
f = State Tag (() -> (a, PrimQuery)) -> QueryArr () a
forall a b. State Tag (a -> (b, PrimQuery)) -> QueryArr a b
productQueryArr' (((a, PrimQuery) -> () -> (a, PrimQuery))
-> State Tag (a, PrimQuery) -> State Tag (() -> (a, PrimQuery))
forall a b.
(a -> b) -> StateT Tag Identity a -> StateT Tag Identity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a, PrimQuery) -> () -> (a, PrimQuery)
forall a b. a -> b -> a
const State Tag (a, PrimQuery)
f)

productQueryArr' :: State Tag (a -> (b, PQ.PrimQuery)) -> QueryArr a b
productQueryArr' :: forall a b. State Tag (a -> (b, PrimQuery)) -> QueryArr a b
productQueryArr' State Tag (a -> (b, PrimQuery))
f = (a -> State Tag (b, PrimQueryArr)) -> SelectArr a b
forall a b. (a -> State Tag (b, PrimQueryArr)) -> SelectArr a b
QueryArr ((a -> State Tag (b, PrimQueryArr)) -> SelectArr a b)
-> (a -> State Tag (b, PrimQueryArr)) -> SelectArr a b
forall a b. (a -> b) -> a -> b
$ \a
a -> do
  a -> (b, PrimQuery)
t <- State Tag (a -> (b, PrimQuery))
f
  (b, PrimQueryArr) -> State Tag (b, PrimQueryArr)
forall a. a -> StateT Tag Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((b, PrimQueryArr) -> State Tag (b, PrimQueryArr))
-> (b, PrimQueryArr) -> State Tag (b, PrimQueryArr)
forall a b. (a -> b) -> a -> b
$
    let (b
b, PrimQuery
pq) = a -> (b, PrimQuery)
t a
a
    in (b
b, PrimQuery -> PrimQueryArr
PQ.aProduct PrimQuery
pq)

leftJoinQueryArr' :: State Tag (a -> (b, HPQ.PrimExpr, PQ.PrimQuery)) -> QueryArr a b
leftJoinQueryArr' :: forall a b.
State Tag (a -> (b, PrimExpr, PrimQuery)) -> QueryArr a b
leftJoinQueryArr' State Tag (a -> (b, PrimExpr, PrimQuery))
f = State Tag (a -> (b, PrimQueryArr)) -> SelectArr a b
forall a b. State Tag (a -> (b, PrimQueryArr)) -> SelectArr a b
selectArr (State Tag (a -> (b, PrimQueryArr)) -> SelectArr a b)
-> State Tag (a -> (b, PrimQueryArr)) -> SelectArr a b
forall a b. (a -> b) -> a -> b
$ do
  a -> (b, PrimExpr, PrimQuery)
t <- State Tag (a -> (b, PrimExpr, PrimQuery))
f
  (a -> (b, PrimQueryArr)) -> State Tag (a -> (b, PrimQueryArr))
forall a. a -> StateT Tag Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((a -> (b, PrimQueryArr)) -> State Tag (a -> (b, PrimQueryArr)))
-> (a -> (b, PrimQueryArr)) -> State Tag (a -> (b, PrimQueryArr))
forall a b. (a -> b) -> a -> b
$ \a
a ->
    let (b
a1, PrimExpr
cond, PrimQuery
primQuery') = a -> (b, PrimExpr, PrimQuery)
t a
a
    in (b
a1, PrimExpr -> PrimQuery -> PrimQueryArr
PQ.aLeftJoin PrimExpr
cond PrimQuery
primQuery')

runSimpleSelect :: Select a -> State Tag (a, PQ.PrimQuery)
runSimpleSelect :: forall a. Select a -> State Tag (a, PrimQuery)
runSimpleSelect Select a
s = Select a -> () -> State Tag (a, PrimQuery)
forall a b. QueryArr a b -> a -> State Tag (b, PrimQuery)
runSimpleQueryArr' Select a
s ()

runSimpleQueryArr' :: QueryArr a b -> a -> State Tag (b, PQ.PrimQuery)
runSimpleQueryArr' :: forall a b. QueryArr a b -> a -> State Tag (b, PrimQuery)
runSimpleQueryArr' QueryArr a b
f a
a = do
  (b
b, PrimQueryArr
pqf) <- QueryArr a b -> a -> State Tag (b, PrimQueryArr)
forall a b. SelectArr a b -> a -> State Tag (b, PrimQueryArr)
unQueryArr QueryArr a b
f a
a
  (b, PrimQuery) -> State Tag (b, PrimQuery)
forall a. a -> StateT Tag Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b
b, PrimQueryArr -> PrimQuery
PQ.toPrimQuery PrimQueryArr
pqf)

-- This is used by Rel8, but at some point it should switch to
-- runSimpleQueryArr' instead.
runStateQueryArr :: QueryArr a b -> a -> Tag -> (b, PQ.PrimQueryArr, Tag)
runStateQueryArr :: forall a b. QueryArr a b -> a -> Tag -> (b, PrimQueryArr, Tag)
runStateQueryArr (QueryArr a -> State Tag (b, PrimQueryArr)
f) a
a Tag
tag =
  let ((b
b, PrimQueryArr
pq), Tag
tag') = State Tag (b, PrimQueryArr) -> Tag -> ((b, PrimQueryArr), Tag)
forall s a. State s a -> s -> (a, s)
runState (a -> State Tag (b, PrimQueryArr)
f a
a) Tag
tag
  in (b
b, PrimQueryArr
pq, Tag
tag')

-- This is used by Rel8, but at some point it should switch to
-- selectArr instead.
stateQueryArr :: (a -> Tag -> (b, PQ.PrimQueryArr, Tag)) -> QueryArr a b
stateQueryArr :: forall a b. (a -> Tag -> (b, PrimQueryArr, Tag)) -> QueryArr a b
stateQueryArr a -> Tag -> (b, PrimQueryArr, Tag)
f = (a -> State Tag (b, PrimQueryArr)) -> SelectArr a b
forall a b. (a -> State Tag (b, PrimQueryArr)) -> SelectArr a b
QueryArr ((a -> State Tag (b, PrimQueryArr)) -> SelectArr a b)
-> (a -> State Tag (b, PrimQueryArr)) -> SelectArr a b
forall a b. (a -> b) -> a -> b
$ \a
a -> (Tag -> ((b, PrimQueryArr), Tag)) -> State Tag (b, PrimQueryArr)
forall (m :: * -> *) s a. Monad m => (s -> (a, s)) -> StateT s m a
state ((Tag -> ((b, PrimQueryArr), Tag)) -> State Tag (b, PrimQueryArr))
-> (Tag -> ((b, PrimQueryArr), Tag)) -> State Tag (b, PrimQueryArr)
forall a b. (a -> b) -> a -> b
$ \Tag
tag ->
  let (b
b, PrimQueryArr
pq, Tag
tag') = a -> Tag -> (b, PrimQueryArr, Tag)
f a
a Tag
tag
  in ((b
b, PrimQueryArr
pq), Tag
tag')

-- This is used by Rel8, but at some point it should switch to
-- runSimpleSelectStart
runSimpleQueryArrStart :: QueryArr a b -> a -> (b, PQ.PrimQuery, Tag)
runSimpleQueryArrStart :: forall a b. QueryArr a b -> a -> (b, PrimQuery, Tag)
runSimpleQueryArrStart QueryArr a b
q a
a =
  let ((b
b, PrimQuery
pqa), Tag
t') = State Tag (b, PrimQuery) -> Tag -> ((b, PrimQuery), Tag)
forall s a. State s a -> s -> (a, s)
runState (QueryArr a b -> a -> State Tag (b, PrimQuery)
forall a b. QueryArr a b -> a -> State Tag (b, PrimQuery)
runSimpleQueryArr' QueryArr a b
q a
a) Tag
Tag.start
  in (b
b, PrimQuery
pqa, Tag
t')

runSimpleSelectStart :: Select a -> (a, PQ.PrimQuery)
runSimpleSelectStart :: forall a. Select a -> (a, PrimQuery)
runSimpleSelectStart = (State Tag (a, PrimQuery) -> Tag -> (a, PrimQuery))
-> Tag -> State Tag (a, PrimQuery) -> (a, PrimQuery)
forall a b c. (a -> b -> c) -> b -> a -> c
flip State Tag (a, PrimQuery) -> Tag -> (a, PrimQuery)
forall s a. State s a -> s -> a
evalState Tag
Tag.start (State Tag (a, PrimQuery) -> (a, PrimQuery))
-> (Select a -> State Tag (a, PrimQuery))
-> Select a
-> (a, PrimQuery)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Select a -> State Tag (a, PrimQuery)
forall a. Select a -> State Tag (a, PrimQuery)
runSimpleSelect

runQueryArrUnpack :: U.Unpackspec a b
                  -> Query a -> ([HPQ.PrimExpr], PQ.PrimQuery, Tag)
runQueryArrUnpack :: forall a b.
Unpackspec a b -> Query a -> ([PrimExpr], PrimQuery, Tag)
runQueryArrUnpack Unpackspec a b
unpackspec Query a
q = ([PrimExpr]
primExprs, PrimQuery
primQ, Tag
endTag)
  where (a
columns, PrimQuery
primQ, Tag
endTag) = Query a -> () -> (a, PrimQuery, Tag)
forall a b. QueryArr a b -> a -> (b, PrimQuery, Tag)
runSimpleQueryArrStart Query a
q ()
        primExprs :: [PrimExpr]
primExprs = Unpackspec a b -> a -> [PrimExpr]
forall s t. Unpackspec s t -> s -> [PrimExpr]
U.collectPEs Unpackspec a b
unpackspec a
columns

-- | A @SELECT@, i.e. an SQL query which produces a collection of
-- rows.
--
-- @Select a@ is analogous to a Haskell value @[a]@.
type Select = SelectArr ()

-- | Implements @LATERAL@ subqueries.
--
-- You might find it easier to use 'Opaleye.Lateral.laterally' (if you
-- want to apply 'Opaleye.Aggregate.aggregate',
-- 'Opaleye.Order.orderBy' or 'Opaleye.Order.limit' to a 'SelectArr')
-- or 'Opaleye.Lateral.bilaterally' (if you want to apply
-- 'Opaleye.Binary.union', 'Opaleye.Binary.intersect' and
-- 'Opaleye.Binary.except' to two 'SelectArr's).
lateral :: (i -> Select a) -> SelectArr i a
lateral :: forall i a. (i -> Select a) -> SelectArr i a
lateral i -> Select a
f = (i -> State Tag (a, PrimQueryArr)) -> SelectArr i a
forall a b. (a -> State Tag (b, PrimQueryArr)) -> SelectArr a b
QueryArr ((i -> State Tag (a, PrimQueryArr)) -> SelectArr i a)
-> (i -> State Tag (a, PrimQueryArr)) -> SelectArr i a
forall a b. (a -> b) -> a -> b
$ \i
i -> do
  (a
a, PrimQueryArr
primQueryR) <- Select a -> () -> State Tag (a, PrimQueryArr)
forall a b. SelectArr a b -> a -> State Tag (b, PrimQueryArr)
unQueryArr (i -> Select a
f i
i) ()
  (a, PrimQueryArr) -> State Tag (a, PrimQueryArr)
forall a. a -> StateT Tag Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
a, PrimQueryArr -> PrimQueryArr
PQ.lateral PrimQueryArr
primQueryR)

-- | Convert an arrow argument into a function argument so that it can
-- be applied inside @do@-notation rather than arrow notation.
viaLateral :: SelectArr i a -> i -> Select a
viaLateral :: forall i a. SelectArr i a -> i -> Select a
viaLateral SelectArr i a
s i
i = SelectArr i a
s SelectArr i a -> SelectArr () i -> SelectArr () a
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
<<< i -> SelectArr () i
forall a. a -> SelectArr () a
forall (f :: * -> *) a. Applicative f => a -> f a
pure i
i

bind :: SelectArr i a -> (a -> SelectArr i b) -> SelectArr i b
bind :: forall i a b.
SelectArr i a -> (a -> SelectArr i b) -> SelectArr i b
bind SelectArr i a
s a -> SelectArr i b
f = proc i
i -> do
  a
a <- SelectArr i a
s -< i
i
  b
b <- ((a, i) -> Select b) -> SelectArr (a, i) b
forall i a. (i -> Select a) -> SelectArr i a
lateral (\(a
a, i
i) -> SelectArr i b -> i -> Select b
forall i a. SelectArr i a -> i -> Select a
viaLateral (a -> SelectArr i b
f a
a) i
i) -< (a
a, i
i)
  SelectArr b b
forall (a :: * -> * -> *) b. Arrow a => a b b
returnA -< b
b

arrowApply :: SelectArr (SelectArr i a, i) a
arrowApply :: forall i a. SelectArr (SelectArr i a, i) a
arrowApply = ((SelectArr i a, i) -> Select a) -> SelectArr (SelectArr i a, i) a
forall i a. (i -> Select a) -> SelectArr i a
lateral (\(SelectArr i a
f, i
i) -> SelectArr i a -> i -> Select a
forall i a. SelectArr i a -> i -> Select a
viaLateral SelectArr i a
f i
i)

instance C.Category QueryArr where
  id :: forall a. QueryArr a a
id = (a -> a) -> SelectArr a a
forall b c. (b -> c) -> SelectArr b c
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr a -> a
forall a. a -> a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
  QueryArr b -> State Tag (c, PrimQueryArr)
f . :: forall b c a. QueryArr b c -> QueryArr a b -> QueryArr a c
. QueryArr a -> State Tag (b, PrimQueryArr)
g = (a -> State Tag (c, PrimQueryArr)) -> SelectArr a c
forall a b. (a -> State Tag (b, PrimQueryArr)) -> SelectArr a b
QueryArr ((a -> State Tag (c, PrimQueryArr)) -> SelectArr a c)
-> (a -> State Tag (c, PrimQueryArr)) -> SelectArr a c
forall a b. (a -> b) -> a -> b
$ \a
a -> do
    (b
b, PrimQueryArr
pqf)  <- a -> State Tag (b, PrimQueryArr)
g a
a
    (c
c, PrimQueryArr
pqf') <- b -> State Tag (c, PrimQueryArr)
f b
b
    (c, PrimQueryArr) -> State Tag (c, PrimQueryArr)
forall a. a -> StateT Tag Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (c
c, PrimQueryArr
pqf PrimQueryArr -> PrimQueryArr -> PrimQueryArr
forall a. Semigroup a => a -> a -> a
<> PrimQueryArr
pqf')

instance Arr.Arrow QueryArr where
  arr :: forall b c. (b -> c) -> SelectArr b c
arr b -> c
f   = (b -> State Tag (c, PrimQueryArr)) -> SelectArr b c
forall a b. (a -> State Tag (b, PrimQueryArr)) -> SelectArr a b
QueryArr (\b
a -> (c, PrimQueryArr) -> State Tag (c, PrimQueryArr)
forall a. a -> StateT Tag Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b -> c
f b
a, PrimQueryArr
forall a. Monoid a => a
mempty))
  first :: forall b c d. QueryArr b c -> QueryArr (b, d) (c, d)
first (QueryArr b -> State Tag (c, PrimQueryArr)
f) = ((b, d) -> State Tag ((c, d), PrimQueryArr))
-> SelectArr (b, d) (c, d)
forall a b. (a -> State Tag (b, PrimQueryArr)) -> SelectArr a b
QueryArr (b, d) -> State Tag ((c, d), PrimQueryArr)
forall {b}. (b, b) -> StateT Tag Identity ((c, b), PrimQueryArr)
g
    where g :: (b, b) -> StateT Tag Identity ((c, b), PrimQueryArr)
g (b
b, b
d) = do
            (c
c, PrimQueryArr
pq) <- b -> State Tag (c, PrimQueryArr)
f b
b
            ((c, b), PrimQueryArr)
-> StateT Tag Identity ((c, b), PrimQueryArr)
forall a. a -> StateT Tag Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((c
c, b
d), PrimQueryArr
pq)

instance Arr.ArrowChoice QueryArr where
  left :: forall b c d. QueryArr b c -> QueryArr (Either b d) (Either c d)
left (QueryArr b -> State Tag (c, PrimQueryArr)
f) = (Either b d -> State Tag (Either c d, PrimQueryArr))
-> SelectArr (Either b d) (Either c d)
forall a b. (a -> State Tag (b, PrimQueryArr)) -> SelectArr a b
QueryArr Either b d -> State Tag (Either c d, PrimQueryArr)
forall {b}.
Either b b -> StateT Tag Identity (Either c b, PrimQueryArr)
g
    where g :: Either b b -> StateT Tag Identity (Either c b, PrimQueryArr)
g Either b b
e = case Either b b
e of
            Left b
a -> do
              (c
r, PrimQueryArr
pq) <- b -> State Tag (c, PrimQueryArr)
f b
a
              (Either c b, PrimQueryArr)
-> StateT Tag Identity (Either c b, PrimQueryArr)
forall a. a -> StateT Tag Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (c -> Either c b
forall a b. a -> Either a b
Left c
r, PrimQueryArr
pq)
            Right b
b -> (Either c b, PrimQueryArr)
-> StateT Tag Identity (Either c b, PrimQueryArr)
forall a. a -> StateT Tag Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (b -> Either c b
forall a b. b -> Either a b
Right b
b, PrimQueryArr
forall a. Monoid a => a
mempty)

instance Arr.ArrowApply QueryArr where
  app :: forall i a. SelectArr (SelectArr i a, i) a
app = SelectArr (SelectArr b c, b) c
forall i a. SelectArr (SelectArr i a, i) a
arrowApply

instance Functor (QueryArr a) where
  fmap :: forall a b. (a -> b) -> QueryArr a a -> QueryArr a b
fmap a -> b
f = ((a -> b) -> SelectArr a b
forall b c. (b -> c) -> SelectArr b c
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr a -> b
f SelectArr a b -> SelectArr a a -> SelectArr a b
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
<<<)

instance Applicative (QueryArr a) where
  pure :: forall a. a -> QueryArr a a
pure = (a -> a) -> SelectArr a a
forall b c. (b -> c) -> SelectArr b c
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr ((a -> a) -> SelectArr a a) -> (a -> a -> a) -> a -> SelectArr a a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a -> a
forall a b. a -> b -> a
const
  QueryArr a (a -> b)
f <*> :: forall a b. QueryArr a (a -> b) -> QueryArr a a -> QueryArr a b
<*> QueryArr a a
g = ((a -> b, a) -> b) -> SelectArr (a -> b, a) b
forall b c. (b -> c) -> SelectArr b c
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr (((a -> b) -> a -> b) -> (a -> b, a) -> b
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (a -> b) -> a -> b
forall a b. (a -> b) -> a -> b
($)) SelectArr (a -> b, a) b -> SelectArr a (a -> b, a) -> SelectArr a b
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
<<< (QueryArr a (a -> b)
f QueryArr a (a -> b) -> QueryArr a a -> SelectArr a (a -> b, a)
forall b c c'. QueryArr b c -> QueryArr b c' -> QueryArr b (c, c')
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& QueryArr a a
g)

instance Monad (QueryArr a) where
  return :: forall a. a -> QueryArr a a
return = a -> SelectArr a a
forall a. a -> QueryArr a a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
  >>= :: forall a b. QueryArr a a -> (a -> QueryArr a b) -> QueryArr a b
(>>=) = SelectArr a a -> (a -> SelectArr a b) -> SelectArr a b
forall i a b.
SelectArr i a -> (a -> SelectArr i b) -> SelectArr i b
bind

instance P.Profunctor QueryArr where
  dimap :: forall a b c d.
(a -> b) -> (c -> d) -> QueryArr b c -> QueryArr a d
dimap a -> b
f c -> d
g QueryArr b c
a = (c -> d) -> SelectArr c d
forall b c. (b -> c) -> SelectArr b c
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr c -> d
g SelectArr c d -> SelectArr a c -> SelectArr a d
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
<<< QueryArr b c
a QueryArr b c -> SelectArr a b -> SelectArr a c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
<<< (a -> b) -> SelectArr a b
forall b c. (b -> c) -> SelectArr b c
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr a -> b
f

instance PP.ProductProfunctor QueryArr where
  empty :: QueryArr () ()
empty = QueryArr () ()
forall a. QueryArr a a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
  ***! :: forall b c b' c'.
QueryArr b c -> QueryArr b' c' -> QueryArr (b, b') (c, c')
(***!) = SelectArr a b -> SelectArr a' b' -> SelectArr (a, a') (b, b')
forall b c b' c'.
QueryArr b c -> QueryArr b' c' -> QueryArr (b, b') (c, c')
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
(***)