{-# language DerivingVia #-}
{-# language GeneralizedNewtypeDeriving #-}
{-# language StandaloneKindSignatures #-}

module Rel8.Query
  ( Query( Query )
  )
where

-- base
import Data.Kind ( Type )
import Prelude

-- opaleye
import qualified Opaleye.Select as Opaleye

-- rel8
import Rel8.Query.Set ( unionAll )
import Rel8.Query.Values ( values )
import Rel8.Table.Alternative
  ( AltTable, (<|>:)
  , AlternativeTable, emptyTable
  )

-- semigroupoids
import Data.Functor.Apply ( Apply, WrappedApplicative(..) )
import Data.Functor.Bind ( Bind, (>>-) )


-- | The @Query@ monad allows you to compose a @SELECT@ query. This monad has
-- semantics similar to the list (@[]@) monad.
type Query :: Type -> Type
newtype Query a = Query (Opaleye.Select a)
  deriving newtype (a -> Query b -> Query a
(a -> b) -> Query a -> Query b
(forall a b. (a -> b) -> Query a -> Query b)
-> (forall a b. a -> Query b -> Query a) -> Functor Query
forall a b. a -> Query b -> Query a
forall a b. (a -> b) -> Query a -> Query b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Query b -> Query a
$c<$ :: forall a b. a -> Query b -> Query a
fmap :: (a -> b) -> Query a -> Query b
$cfmap :: forall a b. (a -> b) -> Query a -> Query b
Functor, Functor Query
a -> Query a
Functor Query
-> (forall a. a -> Query a)
-> (forall a b. Query (a -> b) -> Query a -> Query b)
-> (forall a b c. (a -> b -> c) -> Query a -> Query b -> Query c)
-> (forall a b. Query a -> Query b -> Query b)
-> (forall a b. Query a -> Query b -> Query a)
-> Applicative Query
Query a -> Query b -> Query b
Query a -> Query b -> Query a
Query (a -> b) -> Query a -> Query b
(a -> b -> c) -> Query a -> Query b -> Query c
forall a. a -> Query a
forall a b. Query a -> Query b -> Query a
forall a b. Query a -> Query b -> Query b
forall a b. Query (a -> b) -> Query a -> Query b
forall a b c. (a -> b -> c) -> Query a -> Query b -> Query c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: Query a -> Query b -> Query a
$c<* :: forall a b. Query a -> Query b -> Query a
*> :: Query a -> Query b -> Query b
$c*> :: forall a b. Query a -> Query b -> Query b
liftA2 :: (a -> b -> c) -> Query a -> Query b -> Query c
$cliftA2 :: forall a b c. (a -> b -> c) -> Query a -> Query b -> Query c
<*> :: Query (a -> b) -> Query a -> Query b
$c<*> :: forall a b. Query (a -> b) -> Query a -> Query b
pure :: a -> Query a
$cpure :: forall a. a -> Query a
$cp1Applicative :: Functor Query
Applicative, Applicative Query
a -> Query a
Applicative Query
-> (forall a b. Query a -> (a -> Query b) -> Query b)
-> (forall a b. Query a -> Query b -> Query b)
-> (forall a. a -> Query a)
-> Monad Query
Query a -> (a -> Query b) -> Query b
Query a -> Query b -> Query b
forall a. a -> Query a
forall a b. Query a -> Query b -> Query b
forall a b. Query a -> (a -> Query b) -> Query b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> Query a
$creturn :: forall a. a -> Query a
>> :: Query a -> Query b -> Query b
$c>> :: forall a b. Query a -> Query b -> Query b
>>= :: Query a -> (a -> Query b) -> Query b
$c>>= :: forall a b. Query a -> (a -> Query b) -> Query b
$cp1Monad :: Applicative Query
Monad)
  deriving Functor Query
Functor Query
-> (forall a b. Query (a -> b) -> Query a -> Query b)
-> (forall a b. Query a -> Query b -> Query b)
-> (forall a b. Query a -> Query b -> Query a)
-> (forall a b c. (a -> b -> c) -> Query a -> Query b -> Query c)
-> Apply Query
Query a -> Query b -> Query b
Query a -> Query b -> Query a
Query (a -> b) -> Query a -> Query b
(a -> b -> c) -> Query a -> Query b -> Query c
forall a b. Query a -> Query b -> Query a
forall a b. Query a -> Query b -> Query b
forall a b. Query (a -> b) -> Query a -> Query b
forall a b c. (a -> b -> c) -> Query a -> Query b -> Query c
forall (f :: * -> *).
Functor f
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> Apply f
liftF2 :: (a -> b -> c) -> Query a -> Query b -> Query c
$cliftF2 :: forall a b c. (a -> b -> c) -> Query a -> Query b -> Query c
<. :: Query a -> Query b -> Query a
$c<. :: forall a b. Query a -> Query b -> Query a
.> :: Query a -> Query b -> Query b
$c.> :: forall a b. Query a -> Query b -> Query b
<.> :: Query (a -> b) -> Query a -> Query b
$c<.> :: forall a b. Query (a -> b) -> Query a -> Query b
$cp1Apply :: Functor Query
Apply via (WrappedApplicative Opaleye.Select)


instance Bind Query where
  >>- :: Query a -> (a -> Query b) -> Query b
(>>-) = Query a -> (a -> Query b) -> Query b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
(>>=)


-- | '<|>:' = 'unionAll'.
instance AltTable Query where
  <|>: :: Query a -> Query a -> Query a
(<|>:) = Query a -> Query a -> Query a
forall a. Table Expr a => Query a -> Query a -> Query a
unionAll


-- | 'emptyTable' = 'values' @[]@.
instance AlternativeTable Query where
  emptyTable :: Query a
emptyTable = [a] -> Query a
forall a (f :: * -> *).
(Table Expr a, Foldable f) =>
f a -> Query a
values []