    {-# LANGUAGE CPP #-}
    {-# LANGUAGE StandaloneDeriving #-}
    {-# LANGUAGE GeneralizedNewtypeDeriving #-}

    module Database.Redis.Core.Internal where
    #if __GLASGOW_HASKELL__ > 711 && __GLASGOW_HASKELL__ < 808
    import Control.Monad.Fail (MonadFail)
    #endif
    import Control.Monad.Reader
    import Data.IORef
    import Database.Redis.Protocol
    import Control.Monad.IO.Unlift (MonadUnliftIO)
    import qualified Database.Redis.ProtocolPipelining as PP
    import qualified Database.Redis.Cluster as Cluster

    -- |Context for normal command execution, outside of transactions. Use
    --  'runRedis' to run actions of this type.
    --
    --  In this context, each result is wrapped in an 'Either' to account for the
    --  possibility of Redis returning an 'Error' reply.
    newtype Redis a =
      Redis (ReaderT RedisEnv IO a)
      deriving (Applicative Redis
    Applicative Redis
    -> (forall a b. Redis a -> (a -> Redis b) -> Redis b)
    -> (forall a b. Redis a -> Redis b -> Redis b)
    -> (forall a. a -> Redis a)
    -> Monad Redis
    forall a. a -> Redis a
    forall a b. Redis a -> Redis b -> Redis b
    forall a b. Redis a -> (a -> Redis b) -> Redis 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
    $c>>= :: forall a b. Redis a -> (a -> Redis b) -> Redis b
    >>= :: forall a b. Redis a -> (a -> Redis b) -> Redis b
    $c>> :: forall a b. Redis a -> Redis b -> Redis b
    >> :: forall a b. Redis a -> Redis b -> Redis b
    $creturn :: forall a. a -> Redis a
    return :: forall a. a -> Redis a
    Monad, Monad Redis
    Monad Redis -> (forall a. IO a -> Redis a) -> MonadIO Redis
    forall a. IO a -> Redis a
    forall (m :: * -> *).
    Monad m -> (forall a. IO a -> m a) -> MonadIO m
    $cliftIO :: forall a. IO a -> Redis a
    liftIO :: forall a. IO a -> Redis a
    MonadIO, (forall a b. (a -> b) -> Redis a -> Redis b)
    -> (forall a b. a -> Redis b -> Redis a) -> Functor Redis
    forall a b. a -> Redis b -> Redis a
    forall a b. (a -> b) -> Redis a -> Redis b
    forall (f :: * -> *).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    $cfmap :: forall a b. (a -> b) -> Redis a -> Redis b
    fmap :: forall a b. (a -> b) -> Redis a -> Redis b
    $c<$ :: forall a b. a -> Redis b -> Redis a
    <$ :: forall a b. a -> Redis b -> Redis a
    Functor, Functor Redis
    Functor Redis
    -> (forall a. a -> Redis a)
    -> (forall a b. Redis (a -> b) -> Redis a -> Redis b)
    -> (forall a b c. (a -> b -> c) -> Redis a -> Redis b -> Redis c)
    -> (forall a b. Redis a -> Redis b -> Redis b)
    -> (forall a b. Redis a -> Redis b -> Redis a)
    -> Applicative Redis
    forall a. a -> Redis a
    forall a b. Redis a -> Redis b -> Redis a
    forall a b. Redis a -> Redis b -> Redis b
    forall a b. Redis (a -> b) -> Redis a -> Redis b
    forall a b c. (a -> b -> c) -> Redis a -> Redis b -> Redis 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
    $cpure :: forall a. a -> Redis a
    pure :: forall a. a -> Redis a
    $c<*> :: forall a b. Redis (a -> b) -> Redis a -> Redis b
    <*> :: forall a b. Redis (a -> b) -> Redis a -> Redis b
    $cliftA2 :: forall a b c. (a -> b -> c) -> Redis a -> Redis b -> Redis c
    liftA2 :: forall a b c. (a -> b -> c) -> Redis a -> Redis b -> Redis c
    $c*> :: forall a b. Redis a -> Redis b -> Redis b
    *> :: forall a b. Redis a -> Redis b -> Redis b
    $c<* :: forall a b. Redis a -> Redis b -> Redis a
    <* :: forall a b. Redis a -> Redis b -> Redis a
    Applicative, MonadIO Redis
    MonadIO Redis
    -> (forall b. ((forall a. Redis a -> IO a) -> IO b) -> Redis b)
    -> MonadUnliftIO Redis
    forall b. ((forall a. Redis a -> IO a) -> IO b) -> Redis b
    forall (m :: * -> *).
    MonadIO m
    -> (forall b. ((forall a. m a -> IO a) -> IO b) -> m b)
    -> MonadUnliftIO m
    $cwithRunInIO :: forall b. ((forall a. Redis a -> IO a) -> IO b) -> Redis b
    withRunInIO :: forall b. ((forall a. Redis a -> IO a) -> IO b) -> Redis b
    MonadUnliftIO)
    #if __GLASGOW_HASKELL__ > 711
    deriving instance MonadFail Redis
    #endif
    data RedisEnv
        = NonClusteredEnv { RedisEnv -> Connection
    envConn :: PP.Connection, RedisEnv -> IORef Reply
    envLastReply :: IORef Reply }
        | ClusteredEnv
            { RedisEnv -> IO ShardMap
    refreshAction :: IO Cluster.ShardMap
            , RedisEnv -> Connection
    connection :: Cluster.Connection
            }