{-# LANGUAGE FlexibleContexts #-}
module AWS.Lambda.Runtime.Value (
pureRuntime,
pureRuntimeWithContext,
fallibleRuntime,
fallibleRuntimeWithContext,
ioRuntime,
ioRuntimeWithContext,
readerTRuntime,
mRuntimeWithContext
) where
import AWS.Lambda.RuntimeClient (RuntimeClientConfig, getRuntimeClientConfig,
getNextEvent, sendEventError, sendEventSuccess,
sendInitError)
import AWS.Lambda.Combinators (withIOInterface,
withFallibleInterface,
withPureInterface,
withoutContext)
import AWS.Lambda.Context (LambdaContext(..), HasLambdaContext(..), runReaderTLambdaContext)
import AWS.Lambda.Internal (StaticContext, DynamicContext(DynamicContext),
mkContext)
import Control.Applicative ((<*>))
import Control.Exception (SomeException, displayException)
import Control.Monad (forever)
import Control.Monad.Catch (MonadCatch, try)
import Control.Monad.IO.Class (MonadIO, liftIO)
import Control.Monad.Reader (MonadReader, ReaderT, local)
import Data.Aeson (FromJSON, FromJSON, ToJSON, decode, Value)
import Data.Bifunctor (first)
import qualified Data.ByteString.Char8 as BSC
import qualified Data.ByteString.Lazy as BSW
import qualified Data.ByteString.Internal as BSI
import Data.Text (unpack)
import Data.Text.Encoding (decodeUtf8)
import Data.Time.Clock.POSIX (posixSecondsToUTCTime)
import Network.HTTP.Simple (getResponseBody, getResponseHeader)
import System.Environment (setEnv)
import System.Envy (decodeEnv)
exactlyOneHeader :: [a] -> Maybe a
[a
a] = a -> Maybe a
forall a. a -> Maybe a
Just a
a
exactlyOneHeader [a]
_ = Maybe a
forall a. Maybe a
Nothing
maybeToEither :: b -> Maybe a -> Either b a
maybeToEither :: b -> Maybe a -> Either b a
maybeToEither b
b Maybe a
ma = case Maybe a
ma of
Maybe a
Nothing -> b -> Either b a
forall a b. a -> Either a b
Left b
b
Just a
a -> a -> Either b a
forall a b. b -> Either a b
Right a
a
readMaybe :: (Read a) => String -> Maybe a
readMaybe :: String -> Maybe a
readMaybe String
s = case ReadS a
forall a. Read a => ReadS a
reads String
s of
[(a
x,String
"")] -> a -> Maybe a
forall a. a -> Maybe a
Just a
x
[(a, String)]
_ -> Maybe a
forall a. Maybe a
Nothing
decodeHeaderValue :: FromJSON a => BSC.ByteString -> Maybe a
= ByteString -> Maybe a
forall a. FromJSON a => ByteString -> Maybe a
decode (ByteString -> Maybe a)
-> (ByteString -> ByteString) -> ByteString -> Maybe a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Word8] -> ByteString
BSW.pack ([Word8] -> ByteString)
-> (ByteString -> [Word8]) -> ByteString -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Word8) -> String -> [Word8]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Char -> Word8
BSI.c2w (String -> [Word8])
-> (ByteString -> String) -> ByteString -> [Word8]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> String
BSC.unpack
decodeOptionalHeader :: FromJSON a => [BSC.ByteString] -> Maybe (Maybe a)
[ByteString]
header =
case [ByteString]
header of
[] -> Maybe a -> Maybe (Maybe a)
forall a. a -> Maybe a
Just Maybe a
forall a. Maybe a
Nothing
[ByteString
x] -> (a -> Maybe a) -> Maybe a -> Maybe (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Maybe a
forall a. a -> Maybe a
Just (Maybe a -> Maybe (Maybe a)) -> Maybe a -> Maybe (Maybe a)
forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe a
forall a. FromJSON a => ByteString -> Maybe a
decodeHeaderValue ByteString
x
[ByteString]
_ -> Maybe (Maybe a)
forall a. Maybe a
Nothing
runtimeLoop :: (HasLambdaContext r, MonadReader r m, MonadCatch m, MonadIO m, ToJSON result) => RuntimeClientConfig -> StaticContext ->
(Value -> m result) -> m ()
runtimeLoop :: RuntimeClientConfig -> StaticContext -> (Value -> m result) -> m ()
runtimeLoop RuntimeClientConfig
runtimeClientConfig StaticContext
staticContext Value -> m result
fn = do
Response Value
nextRes <- IO (Response Value) -> m (Response Value)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Response Value) -> m (Response Value))
-> IO (Response Value) -> m (Response Value)
forall a b. (a -> b) -> a -> b
$ RuntimeClientConfig -> IO (Response Value)
getNextEvent RuntimeClientConfig
runtimeClientConfig
let reqIdBS :: ByteString
reqIdBS = [ByteString] -> ByteString
forall a. [a] -> a
head ([ByteString] -> ByteString) -> [ByteString] -> ByteString
forall a b. (a -> b) -> a -> b
$ HeaderName -> Response Value -> [ByteString]
forall a. HeaderName -> Response a -> [ByteString]
getResponseHeader HeaderName
"Lambda-Runtime-Aws-Request-Id" Response Value
nextRes
let mTraceId :: Maybe Text
mTraceId = (ByteString -> Text) -> Maybe ByteString -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> Text
decodeUtf8 (Maybe ByteString -> Maybe Text) -> Maybe ByteString -> Maybe Text
forall a b. (a -> b) -> a -> b
$ [ByteString] -> Maybe ByteString
forall a. [a] -> Maybe a
exactlyOneHeader ([ByteString] -> Maybe ByteString)
-> [ByteString] -> Maybe ByteString
forall a b. (a -> b) -> a -> b
$ HeaderName -> Response Value -> [ByteString]
forall a. HeaderName -> Response a -> [ByteString]
getResponseHeader HeaderName
"Lambda-Runtime-Trace-Id" Response Value
nextRes
let mFunctionArn :: Maybe Text
mFunctionArn = (ByteString -> Text) -> Maybe ByteString -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> Text
decodeUtf8 (Maybe ByteString -> Maybe Text) -> Maybe ByteString -> Maybe Text
forall a b. (a -> b) -> a -> b
$ [ByteString] -> Maybe ByteString
forall a. [a] -> Maybe a
exactlyOneHeader ([ByteString] -> Maybe ByteString)
-> [ByteString] -> Maybe ByteString
forall a b. (a -> b) -> a -> b
$ HeaderName -> Response Value -> [ByteString]
forall a. HeaderName -> Response a -> [ByteString]
getResponseHeader HeaderName
"Lambda-Runtime-Invoked-Function-Arn" Response Value
nextRes
let mDeadline :: Maybe UTCTime
mDeadline = do
ByteString
header <- [ByteString] -> Maybe ByteString
forall a. [a] -> Maybe a
exactlyOneHeader (HeaderName -> Response Value -> [ByteString]
forall a. HeaderName -> Response a -> [ByteString]
getResponseHeader HeaderName
"Lambda-Runtime-Deadline-Ms" Response Value
nextRes)
Double
milliseconds :: Double <- String -> Maybe Double
forall a. Read a => String -> Maybe a
readMaybe (String -> Maybe Double) -> String -> Maybe Double
forall a b. (a -> b) -> a -> b
$ ByteString -> String
BSC.unpack ByteString
header
UTCTime -> Maybe UTCTime
forall (m :: * -> *) a. Monad m => a -> m a
return (UTCTime -> Maybe UTCTime) -> UTCTime -> Maybe UTCTime
forall a b. (a -> b) -> a -> b
$ POSIXTime -> UTCTime
posixSecondsToUTCTime (POSIXTime -> UTCTime) -> POSIXTime -> UTCTime
forall a b. (a -> b) -> a -> b
$ Double -> POSIXTime
forall a b. (Real a, Fractional b) => a -> b
realToFrac (Double -> POSIXTime) -> Double -> POSIXTime
forall a b. (a -> b) -> a -> b
$ Double
milliseconds Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
1000
let mClientContext :: Maybe (Maybe ClientContext)
mClientContext = [ByteString] -> Maybe (Maybe ClientContext)
forall a. FromJSON a => [ByteString] -> Maybe (Maybe a)
decodeOptionalHeader ([ByteString] -> Maybe (Maybe ClientContext))
-> [ByteString] -> Maybe (Maybe ClientContext)
forall a b. (a -> b) -> a -> b
$ HeaderName -> Response Value -> [ByteString]
forall a. HeaderName -> Response a -> [ByteString]
getResponseHeader HeaderName
"Lambda-Runtime-Client-Context" Response Value
nextRes
let mIdentity :: Maybe (Maybe CognitoIdentity)
mIdentity = [ByteString] -> Maybe (Maybe CognitoIdentity)
forall a. FromJSON a => [ByteString] -> Maybe (Maybe a)
decodeOptionalHeader ([ByteString] -> Maybe (Maybe CognitoIdentity))
-> [ByteString] -> Maybe (Maybe CognitoIdentity)
forall a b. (a -> b) -> a -> b
$ HeaderName -> Response Value -> [ByteString]
forall a. HeaderName -> Response a -> [ByteString]
getResponseHeader HeaderName
"Lambda-Runtime-Cognito-Identity" Response Value
nextRes
let eCtx :: Either String LambdaContext
eCtx =
(DynamicContext -> LambdaContext)
-> Either String DynamicContext -> Either String LambdaContext
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (StaticContext -> DynamicContext -> LambdaContext
mkContext StaticContext
staticContext)
(Either String DynamicContext -> Either String LambdaContext)
-> Either String DynamicContext -> Either String LambdaContext
forall a b. (a -> b) -> a -> b
$ String -> Maybe DynamicContext -> Either String DynamicContext
forall b a. b -> Maybe a -> Either b a
maybeToEither String
"Runtime Error: Unable to decode Context from event response."
(Maybe DynamicContext -> Either String DynamicContext)
-> Maybe DynamicContext -> Either String DynamicContext
forall a b. (a -> b) -> a -> b
$ Text
-> Text
-> Text
-> UTCTime
-> Maybe ClientContext
-> Maybe CognitoIdentity
-> DynamicContext
DynamicContext (ByteString -> Text
decodeUtf8 ByteString
reqIdBS)
(Text
-> Text
-> UTCTime
-> Maybe ClientContext
-> Maybe CognitoIdentity
-> DynamicContext)
-> Maybe Text
-> Maybe
(Text
-> UTCTime
-> Maybe ClientContext
-> Maybe CognitoIdentity
-> DynamicContext)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
mFunctionArn
Maybe
(Text
-> UTCTime
-> Maybe ClientContext
-> Maybe CognitoIdentity
-> DynamicContext)
-> Maybe Text
-> Maybe
(UTCTime
-> Maybe ClientContext -> Maybe CognitoIdentity -> DynamicContext)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe Text
mTraceId
Maybe
(UTCTime
-> Maybe ClientContext -> Maybe CognitoIdentity -> DynamicContext)
-> Maybe UTCTime
-> Maybe
(Maybe ClientContext -> Maybe CognitoIdentity -> DynamicContext)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe UTCTime
mDeadline
Maybe
(Maybe ClientContext -> Maybe CognitoIdentity -> DynamicContext)
-> Maybe (Maybe ClientContext)
-> Maybe (Maybe CognitoIdentity -> DynamicContext)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe (Maybe ClientContext)
mClientContext
Maybe (Maybe CognitoIdentity -> DynamicContext)
-> Maybe (Maybe CognitoIdentity) -> Maybe DynamicContext
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe (Maybe CognitoIdentity)
mIdentity
let event :: Value
event = Response Value -> Value
forall a. Response a -> a
getResponseBody Response Value
nextRes
Either String result
result <- case Either String LambdaContext
eCtx of
Left String
e -> Either String result -> m (Either String result)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String result -> m (Either String result))
-> Either String result -> m (Either String result)
forall a b. (a -> b) -> a -> b
$ String -> Either String result
forall a b. a -> Either a b
Left String
e
Right LambdaContext
ctx ->
(r -> r) -> m (Either String result) -> m (Either String result)
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local (LambdaContext -> r -> r
forall r. HasLambdaContext r => LambdaContext -> r -> r
withContext LambdaContext
ctx) (m (Either String result) -> m (Either String result))
-> m (Either String result) -> m (Either String result)
forall a b. (a -> b) -> a -> b
$ do
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ String -> String -> IO ()
setEnv String
"_X_AMZN_TRACE_ID" (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Text -> String
unpack (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ LambdaContext -> Text
xRayTraceId LambdaContext
ctx
Either SomeException result
caughtResult <- m result -> m (Either SomeException result)
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> m (Either e a)
try (Value -> m result
fn Value
event)
Either String result -> m (Either String result)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String result -> m (Either String result))
-> Either String result -> m (Either String result)
forall a b. (a -> b) -> a -> b
$ (SomeException -> String)
-> Either SomeException result -> Either String result
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (SomeException -> String
forall e. Exception e => e -> String
displayException :: SomeException -> String) Either SomeException result
caughtResult
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ case Either String result
result of
Right result
r -> RuntimeClientConfig -> ByteString -> result -> IO ()
forall a.
ToJSON a =>
RuntimeClientConfig -> ByteString -> a -> IO ()
sendEventSuccess RuntimeClientConfig
runtimeClientConfig ByteString
reqIdBS result
r
Left String
e -> RuntimeClientConfig -> ByteString -> String -> IO ()
sendEventError RuntimeClientConfig
runtimeClientConfig ByteString
reqIdBS String
e
mRuntimeWithContext :: (HasLambdaContext r, MonadCatch m, MonadReader r m, MonadIO m, ToJSON result) =>
(Value -> m result) -> m ()
mRuntimeWithContext :: (Value -> m result) -> m ()
mRuntimeWithContext Value -> m result
fn = do
RuntimeClientConfig
runtimeClientConfig <- IO RuntimeClientConfig -> m RuntimeClientConfig
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO RuntimeClientConfig
getRuntimeClientConfig
Either String StaticContext
possibleStaticCtx <- IO (Either String StaticContext) -> m (Either String StaticContext)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Either String StaticContext)
-> m (Either String StaticContext))
-> IO (Either String StaticContext)
-> m (Either String StaticContext)
forall a b. (a -> b) -> a -> b
$ (IO (Either String StaticContext)
forall a. FromEnv a => IO (Either String a)
decodeEnv :: IO (Either String StaticContext))
case Either String StaticContext
possibleStaticCtx of
Left String
err -> IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ RuntimeClientConfig -> String -> IO ()
sendInitError RuntimeClientConfig
runtimeClientConfig String
err
Right StaticContext
staticContext -> m () -> m ()
forall (f :: * -> *) a b. Applicative f => f a -> f b
forever (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ RuntimeClientConfig -> StaticContext -> (Value -> m result) -> m ()
forall r (m :: * -> *) result.
(HasLambdaContext r, MonadReader r m, MonadCatch m, MonadIO m,
ToJSON result) =>
RuntimeClientConfig -> StaticContext -> (Value -> m result) -> m ()
runtimeLoop RuntimeClientConfig
runtimeClientConfig StaticContext
staticContext Value -> m result
fn
readerTRuntime :: ToJSON result =>
(Value -> ReaderT LambdaContext IO result) -> IO ()
readerTRuntime :: (Value -> ReaderT LambdaContext IO result) -> IO ()
readerTRuntime = ReaderT LambdaContext IO () -> IO ()
forall (m :: * -> *) a. ReaderT LambdaContext m a -> m a
runReaderTLambdaContext (ReaderT LambdaContext IO () -> IO ())
-> ((Value -> ReaderT LambdaContext IO result)
-> ReaderT LambdaContext IO ())
-> (Value -> ReaderT LambdaContext IO result)
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Value -> ReaderT LambdaContext IO result)
-> ReaderT LambdaContext IO ()
forall r (m :: * -> *) result.
(HasLambdaContext r, MonadCatch m, MonadReader r m, MonadIO m,
ToJSON result) =>
(Value -> m result) -> m ()
mRuntimeWithContext
ioRuntimeWithContext :: ToJSON result =>
(LambdaContext -> Value -> IO (Either String result)) -> IO ()
ioRuntimeWithContext :: (LambdaContext -> Value -> IO (Either String result)) -> IO ()
ioRuntimeWithContext = (Value -> ReaderT LambdaContext IO result) -> IO ()
forall result.
ToJSON result =>
(Value -> ReaderT LambdaContext IO result) -> IO ()
readerTRuntime ((Value -> ReaderT LambdaContext IO result) -> IO ())
-> ((LambdaContext -> Value -> IO (Either String result))
-> Value -> ReaderT LambdaContext IO result)
-> (LambdaContext -> Value -> IO (Either String result))
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LambdaContext -> Value -> IO (Either String result))
-> Value -> ReaderT LambdaContext IO result
forall c (m :: * -> *) b a.
(MonadReader c m, MonadIO m) =>
(c -> b -> IO (Either String a)) -> b -> m a
withIOInterface
ioRuntime :: ToJSON result =>
(Value -> IO (Either String result)) -> IO ()
ioRuntime :: (Value -> IO (Either String result)) -> IO ()
ioRuntime = (Value -> ReaderT LambdaContext IO result) -> IO ()
forall result.
ToJSON result =>
(Value -> ReaderT LambdaContext IO result) -> IO ()
readerTRuntime ((Value -> ReaderT LambdaContext IO result) -> IO ())
-> ((Value -> IO (Either String result))
-> Value -> ReaderT LambdaContext IO result)
-> (Value -> IO (Either String result))
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LambdaContext -> Value -> IO (Either String result))
-> Value -> ReaderT LambdaContext IO result
forall c (m :: * -> *) b a.
(MonadReader c m, MonadIO m) =>
(c -> b -> IO (Either String a)) -> b -> m a
withIOInterface ((LambdaContext -> Value -> IO (Either String result))
-> Value -> ReaderT LambdaContext IO result)
-> ((Value -> IO (Either String result))
-> LambdaContext -> Value -> IO (Either String result))
-> (Value -> IO (Either String result))
-> Value
-> ReaderT LambdaContext IO result
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Value -> IO (Either String result))
-> LambdaContext -> Value -> IO (Either String result)
forall a b. a -> b -> a
withoutContext
fallibleRuntimeWithContext :: ToJSON result =>
(LambdaContext -> Value -> Either String result) -> IO ()
fallibleRuntimeWithContext :: (LambdaContext -> Value -> Either String result) -> IO ()
fallibleRuntimeWithContext = (Value -> ReaderT LambdaContext IO result) -> IO ()
forall result.
ToJSON result =>
(Value -> ReaderT LambdaContext IO result) -> IO ()
readerTRuntime ((Value -> ReaderT LambdaContext IO result) -> IO ())
-> ((LambdaContext -> Value -> Either String result)
-> Value -> ReaderT LambdaContext IO result)
-> (LambdaContext -> Value -> Either String result)
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LambdaContext -> Value -> Either String result)
-> Value -> ReaderT LambdaContext IO result
forall c (m :: * -> *) b a.
MonadReader c m =>
(c -> b -> Either String a) -> b -> m a
withFallibleInterface
fallibleRuntime :: ToJSON result =>
(Value -> Either String result) -> IO ()
fallibleRuntime :: (Value -> Either String result) -> IO ()
fallibleRuntime = (Value -> ReaderT LambdaContext IO result) -> IO ()
forall result.
ToJSON result =>
(Value -> ReaderT LambdaContext IO result) -> IO ()
readerTRuntime ((Value -> ReaderT LambdaContext IO result) -> IO ())
-> ((Value -> Either String result)
-> Value -> ReaderT LambdaContext IO result)
-> (Value -> Either String result)
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LambdaContext -> Value -> Either String result)
-> Value -> ReaderT LambdaContext IO result
forall c (m :: * -> *) b a.
MonadReader c m =>
(c -> b -> Either String a) -> b -> m a
withFallibleInterface ((LambdaContext -> Value -> Either String result)
-> Value -> ReaderT LambdaContext IO result)
-> ((Value -> Either String result)
-> LambdaContext -> Value -> Either String result)
-> (Value -> Either String result)
-> Value
-> ReaderT LambdaContext IO result
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Value -> Either String result)
-> LambdaContext -> Value -> Either String result
forall a b. a -> b -> a
withoutContext
pureRuntimeWithContext :: ToJSON result =>
(LambdaContext -> Value -> result) -> IO ()
pureRuntimeWithContext :: (LambdaContext -> Value -> result) -> IO ()
pureRuntimeWithContext = (Value -> ReaderT LambdaContext IO result) -> IO ()
forall result.
ToJSON result =>
(Value -> ReaderT LambdaContext IO result) -> IO ()
readerTRuntime ((Value -> ReaderT LambdaContext IO result) -> IO ())
-> ((LambdaContext -> Value -> result)
-> Value -> ReaderT LambdaContext IO result)
-> (LambdaContext -> Value -> result)
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LambdaContext -> Value -> result)
-> Value -> ReaderT LambdaContext IO result
forall c (m :: * -> *) b a.
MonadReader c m =>
(c -> b -> a) -> b -> m a
withPureInterface
pureRuntime :: ToJSON result => (Value -> result) -> IO ()
pureRuntime :: (Value -> result) -> IO ()
pureRuntime = (Value -> ReaderT LambdaContext IO result) -> IO ()
forall result.
ToJSON result =>
(Value -> ReaderT LambdaContext IO result) -> IO ()
readerTRuntime ((Value -> ReaderT LambdaContext IO result) -> IO ())
-> ((Value -> result) -> Value -> ReaderT LambdaContext IO result)
-> (Value -> result)
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LambdaContext -> Value -> result)
-> Value -> ReaderT LambdaContext IO result
forall c (m :: * -> *) b a.
MonadReader c m =>
(c -> b -> a) -> b -> m a
withPureInterface ((LambdaContext -> Value -> result)
-> Value -> ReaderT LambdaContext IO result)
-> ((Value -> result) -> LambdaContext -> Value -> result)
-> (Value -> result)
-> Value
-> ReaderT LambdaContext IO result
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Value -> result) -> LambdaContext -> Value -> result
forall a b. a -> b -> a
withoutContext