amazonka-mtl-0.1.0.0: library/Control/Monad/AWS/ViaReader.hs
{-# LANGUAGE UndecidableInstances #-}
-- | @DerivingVia@ machinery for adding Amazonka functionality to a reader-like
-- transformer
--
-- This is useful when you have a /ReaderT-IO/-like stack implemented with an
-- @AppT@ wrapper to which you will add the 'MonadAWS' instance:
--
-- @
-- newtype AppT m a = AppT
-- -- ...
-- deriving MonadAWS via (ReaderAWS (AppT m))
-- @
--
-- Complete example:
--
-- @
-- {-# LANGUAGE DerivingVia #-}
--
-- module Main (main) where
--
-- import qualified "Amazonka"
-- import "Control.Lens"
-- import "Control.Monad.AWS"
-- import "Control.Monad.AWS.ViaReader"
-- import "Control.Monad.Reader"
-- import "Control.Monad.Trans.Resource"
--
-- data App = App
-- { -- ...
-- , appAWS :: 'Amazonka.Env'
-- }
--
-- instance HasEnv App where
-- envL = lens appAWS $ \x y -> x { appAWS = y }
--
-- newtype AppT m a = AppT
-- { unAppT :: ReaderT App (ResourceT m) a
-- }
-- deriving newtype
-- ( Functor
-- , Applicative
-- , Monad
-- , MonadIO
-- , MonadUnliftIO
-- , MonadResource
-- , MonadReader App
-- )
-- deriving 'MonadAWS' via ('ReaderAWS' (AppT m))
--
-- runAppT :: MonadUnliftIO m => AppT m a -> App -> m a
-- runAppT f app = runResourceT $ runReaderT (unAppT f) app
--
-- main :: IO ()
-- main = do
-- app <- undefined
-- runAppT someAction app
--
-- someAction :: (MonadIO m, 'MonadAWS' m) => m ()
-- someAction = do
-- resp <- 'send' 'newListBuckets'
-- liftIO $ print resp
-- @
module Control.Monad.AWS.ViaReader
( Env
, HasEnv (..)
, ReaderAWS (..)
) where
import Prelude
import Amazonka.Env
import qualified Amazonka.Send as Amazonka
import Control.Lens (Lens', view)
import Control.Monad.AWS.Class
import Control.Monad.Reader
import Control.Monad.Trans.Resource (MonadResource)
class HasEnv env where
envL :: Lens' env Env
instance HasEnv Env where
envL = id
newtype ReaderAWS m a = ReaderAWS
{ unReaderAWS :: m a
}
deriving newtype
( Functor
, Applicative
, Monad
, MonadIO
, MonadResource
, MonadReader env
)
instance (MonadResource m, MonadReader env m, HasEnv env) => MonadAWS (ReaderAWS m) where
sendEither req = do
env <- view envL
Amazonka.sendEither env req
awaitEither w a = do
env <- view envL
Amazonka.awaitEither env w a