-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A runtime environment for Haskell applications running on AWS Lambda. -- -- This library uniquely supports different types of AWS Lambda Handlers -- for your needs/comfort with advanced Haskell. Instead of exposing a -- single function that constructs a Lambda, this library exposes many. @package hal @version 0.3.3 -- | These combinators are for those who need to peek below the abstraction -- of the basic runtimes, for whatever reason. -- -- They map functions (instead of values) to turn basic handlers into -- handlers compatible with the base runtime. These combinators allow us -- to expose functionality across many dimensions in an abstract way. It -- also allows simple building blocks for those who need to "get in the -- middle" or adapt the basic runtimes in new ways without rebuilding -- everything from the ground up. module AWS.Lambda.Combinators -- | Upgrades a handler that uses the IO monad with an Either -- inside into a base runtime handler. -- -- In the example below, we reconstruct ioRuntimeWithContext -- without actually using it. The readerTRuntime expects a handler -- in the form of event -> ReaderT LambdaContext IO result -- (ignoring constraints). By composing it with withIOInterface we -- get a new runtime which expects a function in the form of -- LambdaContext -> event -> IO result which matches that -- of myHandler. -- --
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Runtime (readerTRuntime)
-- import AWS.Lambda.Combinators (withIOInterface)
-- import Data.Aeson (FromJSON)
-- import System.Environment (getEnv)
--
-- data Named = {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Named -> IO String
-- myHandler (Named { name }) = do
-- greeting <- getEnv "GREETING"
-- return $ greeting ++ name
--
-- main :: IO ()
-- main = (readerTRuntime . withIOInterface) myHandler
--
withIOInterface :: (MonadReader c m, MonadIO m) => (c -> b -> IO (Either String a)) -> b -> m a
-- | Upgrades a handler that accepts LambdaContext and an event to
-- return a value inside an Either inside into a base runtime
-- handler.
--
-- In the example below, we reconstruct fallibleRuntimeWithContext
-- without actually using it. The readerTRuntime expects a handler
-- in the form of event -> ReaderT LambdaContext IO result
-- (ignoring constraints). By composing it with
-- withFallibleInterface we get a new runtime which expects a
-- function in the form of LambdaContext -> event -> Either
-- String result which matches that of myHandler.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Runtime (readerTRuntime)
-- import AWS.Lambda.Combinators (withFallibleInterface)
-- import Data.Aeson (FromJSON)
-- import System.Environment (getEnv)
--
-- data Named = {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: LambdaContext -> Named -> Either String String
-- myHandler (LambdaContext { functionName }) (Named { name }) =
-- if name == "World" then
-- Right "Hello, World from " ++ unpack functionName ++ "!"
-- else
-- Left "Can only greet the world."
--
-- main :: IO ()
-- main = (readerTRuntime . withFallibleInterface) myHandler
--
withFallibleInterface :: MonadReader c m => (c -> b -> Either String a) -> b -> m a
-- | This combinator takes a handler that accepts both an event and
-- LambdaContext and converts it into a handler that is compatible
-- with the base monadic runtime.
--
-- In the example below, we reconstruct pureRuntimeWithContext
-- without actually using it. The readerTRuntime expects a handler
-- in the form of event -> ReaderT LambdaContext IO result
-- (ignoring constraints). By composing it with withPureInterface
-- we get a new runtime which expects a function in the form of
-- LambdaContext -> event -> result which matches that of
-- myHandler.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Runtime (readerTRuntime)
-- import AWS.Lambda.Combinators (withPureInterface)
-- import Data.Aeson (FromJSON)
--
-- data Named = {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: LambdaContext -> Named -> String
-- myHandler (LambdaContext { functionName }) (Named { name }) =
-- "Hello, " ++ name ++ " from " ++ unpack functionName ++ "!"
--
-- main :: IO ()
-- main = (readerTRuntime . withPureInterface) myHandler
--
withPureInterface :: MonadReader c m => (c -> b -> a) -> b -> m a
-- | An alias of const, this upgrades a handler that does not accept
-- LambdaContext as its first curried argument to one that does.
--
-- This allows us to use other combinators to construct a lambda runtime
-- that accepts a handler that ignores LambdaContext.
--
-- In the example below, we reconstruct pureRuntime without
-- actually using it. The readerTRuntime expects a handler in the
-- form of event -> ReaderT LambdaContext IO result (ignoring
-- constraints). By composing it with withPureInterface we get a
-- new runtime which expects a function in the form of LambdaContext
-- -> event -> result, And then finally we also compose
-- withoutContext so it accepts the signature event ->
-- result which matches that of myHandler.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Runtime (readerTRuntime)
-- import AWS.Lambda.Combinators (withPureInterface, withoutContext)
-- import Data.Aeson (FromJSON)
--
-- data Named = {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Named -> String
-- myHandler (Named { name }) =
-- "Hello, " ++ name
--
-- main :: IO ()
-- main = (readerTRuntime . withPureInterface . withoutContext) myHandler
--
withoutContext :: a -> b -> a
module AWS.Lambda.Context
data ClientApplication
ClientApplication :: Text -> Text -> Text -> Text -> ClientApplication
[appTitle] :: ClientApplication -> Text
[appVersionName] :: ClientApplication -> Text
[appVersionCode] :: ClientApplication -> Text
[appPackageName] :: ClientApplication -> Text
data ClientContext
ClientContext :: ClientApplication -> Map Text Text -> Map Text Text -> ClientContext
[client] :: ClientContext -> ClientApplication
[custom] :: ClientContext -> Map Text Text
[environment] :: ClientContext -> Map Text Text
data CognitoIdentity
CognitoIdentity :: Text -> Text -> CognitoIdentity
[identityId] :: CognitoIdentity -> Text
[identityPoolId] :: CognitoIdentity -> Text
data LambdaContext
LambdaContext :: Text -> Text -> Int -> Text -> Text -> Text -> Text -> Text -> UTCTime -> Maybe ClientContext -> Maybe CognitoIdentity -> LambdaContext
[functionName] :: LambdaContext -> Text
[functionVersion] :: LambdaContext -> Text
[functionMemorySize] :: LambdaContext -> Int
[logGroupName] :: LambdaContext -> Text
[logStreamName] :: LambdaContext -> Text
[awsRequestId] :: LambdaContext -> Text
[invokedFunctionArn] :: LambdaContext -> Text
[xRayTraceId] :: LambdaContext -> Text
[deadline] :: LambdaContext -> UTCTime
[clientContext] :: LambdaContext -> Maybe ClientContext
[identity] :: LambdaContext -> Maybe CognitoIdentity
class HasLambdaContext r
withContext :: HasLambdaContext r => LambdaContext -> r -> r
defConfig :: DefConfig a => a
getRemainingTime :: MonadIO m => LambdaContext -> m DiffTime
-- | Helper for using arbitrary monads with only the LambdaContext in its
-- Reader
runReaderTLambdaContext :: ReaderT LambdaContext m a -> m a
instance GHC.Generics.Generic AWS.Lambda.Context.LambdaContext
instance GHC.Show.Show AWS.Lambda.Context.LambdaContext
instance GHC.Generics.Generic AWS.Lambda.Context.CognitoIdentity
instance GHC.Show.Show AWS.Lambda.Context.CognitoIdentity
instance GHC.Generics.Generic AWS.Lambda.Context.ClientContext
instance GHC.Show.Show AWS.Lambda.Context.ClientContext
instance GHC.Generics.Generic AWS.Lambda.Context.ClientApplication
instance GHC.Show.Show AWS.Lambda.Context.ClientApplication
instance AWS.Lambda.Context.HasLambdaContext AWS.Lambda.Context.LambdaContext
instance System.Envy.DefConfig AWS.Lambda.Context.LambdaContext
instance Data.Aeson.Types.ToJSON.ToJSON AWS.Lambda.Context.CognitoIdentity
instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Context.CognitoIdentity
instance Data.Aeson.Types.ToJSON.ToJSON AWS.Lambda.Context.ClientContext
instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Context.ClientContext
instance Data.Aeson.Types.ToJSON.ToJSON AWS.Lambda.Context.ClientApplication
instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Context.ClientApplication
module AWS.Lambda.Events.S3
data PrincipalIdentity
PrincipalIdentity :: Text -> PrincipalIdentity
[$sel:principalId:PrincipalIdentity] :: PrincipalIdentity -> Text
newtype Records
Records :: [S3Event] -> Records
[$sel:records:Records] :: Records -> [S3Event]
data RequestParameters
RequestParameters :: Text -> RequestParameters
[$sel:sourceIPAddress:RequestParameters] :: RequestParameters -> Text
data ResponseElements
ResponseElements :: Text -> Text -> ResponseElements
[$sel:amazonId:ResponseElements] :: ResponseElements -> Text
[$sel:amazonRequestId:ResponseElements] :: ResponseElements -> Text
data S3Bucket
S3Bucket :: Text -> Text -> PrincipalIdentity -> S3Bucket
[$sel:arn:S3Bucket] :: S3Bucket -> Text
[$sel:name:S3Bucket] :: S3Bucket -> Text
[$sel:ownerIdentity:S3Bucket] :: S3Bucket -> PrincipalIdentity
data S3Config
S3Config :: S3Bucket -> Text -> S3Object -> Text -> S3Config
[$sel:bucket:S3Config] :: S3Config -> S3Bucket
[$sel:configurationId:S3Config] :: S3Config -> Text
[$sel:object:S3Config] :: S3Config -> S3Object
[$sel:s3SchemaVersion:S3Config] :: S3Config -> Text
-- | Event data sent by S3 when triggering a Lambda.
data S3Event
S3Event :: Text -> Text -> Text -> UTCTime -> Text -> RequestParameters -> ResponseElements -> S3Config -> PrincipalIdentity -> S3Event
[$sel:awsRegion:S3Event] :: S3Event -> Text
[$sel:eventName:S3Event] :: S3Event -> Text
[$sel:eventSource:S3Event] :: S3Event -> Text
[$sel:eventTime:S3Event] :: S3Event -> UTCTime
[$sel:eventVersion:S3Event] :: S3Event -> Text
[$sel:requestParameters:S3Event] :: S3Event -> RequestParameters
[$sel:responseElements:S3Event] :: S3Event -> ResponseElements
[$sel:s3:S3Event] :: S3Event -> S3Config
[$sel:userIdentity:S3Event] :: S3Event -> PrincipalIdentity
-- | S3 object representations based on event type received.
--
-- Currently only Put/Delete events can trigger Lambdas
data S3Object
PutObject :: Text -> Text -> Text -> Int -> S3Object
[$sel:eTag:PutObject] :: S3Object -> Text
[$sel:sequencer:PutObject] :: S3Object -> Text
[$sel:key:PutObject] :: S3Object -> Text
[$sel:size:PutObject] :: S3Object -> Int
DeleteObject :: Text -> Text -> S3Object
[$sel:sequencer:PutObject] :: S3Object -> Text
[$sel:key:PutObject] :: S3Object -> Text
instance GHC.Classes.Eq AWS.Lambda.Events.S3.Records
instance GHC.Show.Show AWS.Lambda.Events.S3.Records
instance GHC.Generics.Generic AWS.Lambda.Events.S3.S3Event
instance GHC.Classes.Eq AWS.Lambda.Events.S3.S3Event
instance GHC.Show.Show AWS.Lambda.Events.S3.S3Event
instance GHC.Generics.Generic AWS.Lambda.Events.S3.S3Config
instance GHC.Classes.Eq AWS.Lambda.Events.S3.S3Config
instance GHC.Show.Show AWS.Lambda.Events.S3.S3Config
instance GHC.Generics.Generic AWS.Lambda.Events.S3.S3Object
instance GHC.Classes.Eq AWS.Lambda.Events.S3.S3Object
instance GHC.Show.Show AWS.Lambda.Events.S3.S3Object
instance GHC.Generics.Generic AWS.Lambda.Events.S3.RequestParameters
instance GHC.Classes.Eq AWS.Lambda.Events.S3.RequestParameters
instance GHC.Show.Show AWS.Lambda.Events.S3.RequestParameters
instance GHC.Classes.Eq AWS.Lambda.Events.S3.ResponseElements
instance GHC.Show.Show AWS.Lambda.Events.S3.ResponseElements
instance GHC.Generics.Generic AWS.Lambda.Events.S3.S3Bucket
instance GHC.Classes.Eq AWS.Lambda.Events.S3.S3Bucket
instance GHC.Show.Show AWS.Lambda.Events.S3.S3Bucket
instance GHC.Generics.Generic AWS.Lambda.Events.S3.PrincipalIdentity
instance GHC.Classes.Eq AWS.Lambda.Events.S3.PrincipalIdentity
instance GHC.Show.Show AWS.Lambda.Events.S3.PrincipalIdentity
instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.S3.Records
instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.S3.S3Event
instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.S3.S3Config
instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.S3.S3Object
instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.S3.RequestParameters
instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.S3.ResponseElements
instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.S3.S3Bucket
instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.S3.PrincipalIdentity
module AWS.Lambda.Internal
data StaticContext
StaticContext :: Text -> Text -> Int -> Text -> Text -> StaticContext
[functionName] :: StaticContext -> Text
[functionVersion] :: StaticContext -> Text
[functionMemorySize] :: StaticContext -> Int
[logGroupName] :: StaticContext -> Text
[logStreamName] :: StaticContext -> Text
data DynamicContext
DynamicContext :: Text -> Text -> Text -> UTCTime -> Maybe ClientContext -> Maybe CognitoIdentity -> DynamicContext
[awsRequestId] :: DynamicContext -> Text
[invokedFunctionArn] :: DynamicContext -> Text
[xRayTraceId] :: DynamicContext -> Text
[deadline] :: DynamicContext -> UTCTime
[clientContext] :: DynamicContext -> Maybe ClientContext
[identity] :: DynamicContext -> Maybe CognitoIdentity
mkContext :: StaticContext -> DynamicContext -> LambdaContext
instance GHC.Show.Show AWS.Lambda.Internal.DynamicContext
instance GHC.Generics.Generic AWS.Lambda.Internal.StaticContext
instance GHC.Show.Show AWS.Lambda.Internal.StaticContext
instance System.Envy.DefConfig AWS.Lambda.Internal.StaticContext
instance System.Envy.FromEnv AWS.Lambda.Internal.StaticContext
module AWS.Lambda.RuntimeClient
data RuntimeClientConfig
getRuntimeClientConfig :: IO RuntimeClientConfig
getNextEvent :: FromJSON a => RuntimeClientConfig -> IO (Response (Either JSONParseException a))
sendEventSuccess :: ToJSON a => RuntimeClientConfig -> ByteString -> a -> IO ()
sendEventError :: RuntimeClientConfig -> ByteString -> String -> IO ()
sendInitError :: RuntimeClientConfig -> String -> IO ()
instance GHC.Show.Show AWS.Lambda.RuntimeClient.JSONParseException
instance GHC.Generics.Generic AWS.Lambda.RuntimeClient.LambdaError
instance GHC.Show.Show AWS.Lambda.RuntimeClient.LambdaError
instance GHC.Exception.Type.Exception AWS.Lambda.RuntimeClient.JSONParseException
instance Data.Aeson.Types.ToJSON.ToJSON AWS.Lambda.RuntimeClient.LambdaError
-- | These are runtimes designed for AWS Lambda, which accept a handler and
-- return an application that will retreive and execute events as long as
-- a container continues to exist.
--
-- Many of these runtimes use AWS.Lambda.Combinators under the
-- hood. For those interested in peeking below the abstractions provided
-- here, please refer to that module.
module AWS.Lambda.Runtime
-- | For pure functions that can never fail.
--
-- Use this for simple handlers that just translate input to output
-- without side-effects.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Runtime (pureRuntime)
-- import Data.Aeson (FromJSON)
--
-- data Named = {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Named -> String
-- myHandler Named { name } = "Hello, " ++ name ++ "!"
--
-- main :: IO ()
-- main = pureRuntime myHandler
--
pureRuntime :: (FromJSON event, ToJSON result) => (event -> result) -> IO ()
-- | For pure functions that can never fail that also need access to the
-- context.
--
-- Use this for simple handlers that just translate input to output
-- without side-effects, but that need the AWS Lambda Context as input.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..))
-- import AWS.Lambda.Runtime (pureRuntimeWithContext)
-- import Data.Aeson (FromJSON)
-- import Data.Text (unpack)
--
-- data Named = {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: LambdaContext -> Named -> String
-- myHandler (LambdaContext { functionName }) (Named { name }) =
-- "Hello, " ++ name ++ " from " ++ unpack functionName ++ "!"
--
-- main :: IO ()
-- main = pureRuntimeWithContext myHandler
--
pureRuntimeWithContext :: (FromJSON event, ToJSON result) => (LambdaContext -> event -> result) -> IO ()
-- | For pure functions that can still fail.
--
-- Use this for simple handlers that just translate input to output
-- without side-effects, but can fail.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Runtime (fallibleRuntime)
-- import Data.Aeson (FromJSON)
--
-- data Named = {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Named -> Either String String
-- myHandler (Named { name }) =
-- if name == "World" then
-- Right "Hello, World!"
-- else
-- Left "Can only greet the world."
--
-- main :: IO ()
-- main = fallibleRuntime myHandler
--
fallibleRuntime :: (FromJSON event, ToJSON result) => (event -> Either String result) -> IO ()
-- | For pure functions that can still fail.
--
-- Use this for simple handlers that just translate input to output
-- without side-effects, but can fail and need the AWS Lambda Context as
-- input.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..))
-- import AWS.Lambda.Runtime (fallibleRuntimeWithContext)
-- import Data.Aeson (FromJSON)
-- import Data.Text (unpack)
--
-- data Named = {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: LambdaContext -> Named -> Either String String
-- myHandler (LambdaContext { functionName }) (Named { name }) =
-- if name == "World" then
-- Right "Hello, World from " ++ unpack functionName ++ "!"
-- else
-- Left "Can only greet the world."
--
-- main :: IO ()
-- main = fallibleRuntimeWithContext myHandler
--
fallibleRuntimeWithContext :: (FromJSON event, ToJSON result) => (LambdaContext -> event -> Either String result) -> IO ()
-- | For functions with IO that can fail in a pure way (or via throw).
--
-- Use this for handlers that need any form of side-effect such as
-- reading environment variables or making network requests. However, do
-- not use this runtime if you need stateful (caching) behaviors.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Runtime (ioRuntime)
-- import Data.Aeson (FromJSON)
-- import System.Environment (getEnv)
--
-- data Named = {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Named -> IO String
-- myHandler (Named { name }) = do
-- greeting <- getEnv "GREETING"
-- return $ greeting ++ name
--
-- main :: IO ()
-- main = ioRuntime myHandler
--
ioRuntime :: (FromJSON event, ToJSON result) => (event -> IO (Either String result)) -> IO ()
-- | For functions with IO that can fail in a pure way (or via throw).
--
-- Use this for handlers that need any form of side-effect such as
-- reading environment variables or making network requests, and also
-- need the AWS Lambda Context as input. However, do not use this runtime
-- if you need stateful (caching) behaviors.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..))
-- import AWS.Lambda.Runtime (ioRuntimeWithContext)
-- import Data.Aeson (FromJSON)
-- import Data.Text (unpack)
-- import System.Environment (getEnv)
--
-- data Named = {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: LambdaContext -> Named -> IO String
-- myHandler (LambdaContext { functionName }) (Named { name }) = do
-- greeting <- getEnv "GREETING"
-- return $ greeting ++ name ++ " from " ++ unpack functionName ++ "!"
--
-- main :: IO ()
-- main = ioRuntimeWithContext myHandler
--
ioRuntimeWithContext :: (FromJSON event, ToJSON result) => (LambdaContext -> event -> IO (Either String result)) -> IO ()
-- | For functions that can read the lambda context and use IO within the
-- same monad.
--
-- Use this for handlers that need any form of side-effect such as
-- reading environment variables or making network requests, and prefer
-- to access the AWS Lambda Context in the same monad. However, do not
-- use this runtime if you need stateful (caching) behaviors.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..))
-- import AWS.Lambda.Runtime (readerTRuntime)
-- import Control.Monad.Reader (ReaderT, ask)
-- import Data.Aeson (FromJSON)
-- import Data.Text (unpack)
-- import System.Environment (getEnv)
--
-- data Named = {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Named -> ReaderT LambdaContext IO String
-- myHandler Named { name } = do
-- LambdaContext { functionName } <- ask
-- greeting <- getEnv "GREETING"
-- return $ greeting ++ name ++ " from " ++ unpack functionName ++ "!"
--
-- main :: IO ()
-- main = readerTRuntime myHandler
--
readerTRuntime :: (FromJSON event, ToJSON result) => (event -> ReaderT LambdaContext IO result) -> IO ()
-- | For any monad that supports IOcatchReader LambdaContext.
--
-- Use this if you need caching behavours or are comfortable manipulating
-- monad transformers and want full control over your monadic interface.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..))
-- import AWS.Lambda.Runtime (mRuntimeWithContext)
-- import Control.Monad.Reader (ReaderT, ask)
-- import Control.Monad.State.Lazy (StateT, runStateT, get, put)
-- import Data.Aeson (FromJSON)
-- import Data.Text (unpack)
-- import System.Environment (getEnv)
--
-- data Named = {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Named -> StateT Int (ReaderT LambdaContext IO String)
-- myHandler Named { name } = do
-- LambdaContext { functionName } <- ask
-- greeting <- getEnv "GREETING"
--
-- greetingCount <- get
-- put $ greetingCount + 1
--
-- return $ greeting ++ name ++ " (" ++ show greetingCount ++ ") from " ++ unpack functionName ++ "!"
--
-- main :: IO ()
-- main = runStateT (mRuntimeWithContext myHandler) 0
--
mRuntimeWithContext :: (HasLambdaContext r, MonadCatch m, MonadReader r m, MonadIO m, FromJSON event, ToJSON result) => (event -> m result) -> m ()