{-# LANGUAGE
DataKinds
, DefaultSignatures
, FlexibleContexts
, FlexibleInstances
, FunctionalDependencies
, PolyKinds
, MultiParamTypeClasses
, QuantifiedConstraints
, RankNTypes
, TypeApplications
, TypeFamilies
, UndecidableInstances
#-}
module Squeal.PostgreSQL.Session.Indexed
( IndexedMonadTrans (..)
, Indexed (..)
, IndexedMonadTransPQ (..)
, indexedDefine
) where
import Control.Category (Category (..))
import Control.Monad
import Control.Monad.IO.Class
import Control.Monad.Trans
import Data.Function ((&))
import Prelude hiding (id, (.))
import Squeal.PostgreSQL.Definition
class
( forall i j m. Monad m => Functor (t i j m)
, forall i j m. (i ~ j, Monad m) => Monad (t i j m)
, forall i j. i ~ j => MonadTrans (t i j)
) => IndexedMonadTrans t where
{-# MINIMAL pqJoin | pqBind #-}
pqAp
:: Monad m
=> t i j m (x -> y)
-> t j k m x
-> t i k m y
pqAp tf tx = pqBind (<$> tx) tf
pqJoin
:: Monad m
=> t i j m (t j k m y)
-> t i k m y
pqJoin t = t & pqBind id
pqBind
:: Monad m
=> (x -> t j k m y)
-> t i j m x
-> t i k m y
pqBind f t = pqJoin (f <$> t)
pqThen
:: Monad m
=> t j k m y
-> t i j m x
-> t i k m y
pqThen pq2 pq1 = pq1 & pqBind (\ _ -> pq2)
pqAndThen
:: Monad m
=> (y -> t j k m z)
-> (x -> t i j m y)
-> x -> t i k m z
pqAndThen g f x = pqBind g (f x)
newtype Indexed t m r i j = Indexed {runIndexed :: t i j m r}
instance
( IndexedMonadTrans t
, Monad m
, Monoid r
) => Category (Indexed t m r) where
id = Indexed (pure mempty)
Indexed g . Indexed f = Indexed $ pqAp (fmap (<>) f) g
class IndexedMonadTrans pq => IndexedMonadTransPQ pq where
define :: MonadIO io => Definition db0 db1 -> pq db0 db1 io ()
indexedDefine
:: (IndexedMonadTransPQ pq, MonadIO io)
=> Definition db0 db1 -> Indexed pq io () db0 db1
indexedDefine = Indexed . define