-- | A tracing natural transformation morphism over the Session API.
traceSendAPI :: MonadIO m => String -> (SendAPI :~> m) -> (SendAPI :~> m)
traceSendAPI msg f = wrapNT $ \ case
  (Sync v) -> do
          liftIO $ putStrLn $ msg ++ "--> " ++ LT.unpack (decodeUtf8 (encode v))
          r <- f # (Sync v)
          liftIO $ putStrLn $ msg ++ "<-- " ++ LT.unpack (decodeUtf8 (encode r))
          return r
  (Async v) -> do
          liftIO $ putStrLn $ msg ++ "--> " ++ LT.unpack (decodeUtf8 (encode v))
          () <- f # (Async v)
          liftIO $ putStrLn $ msg ++ "// No response"
          return ()

-- | A tracing natural transformation morphism over the Receive API.
traceSendAPI :: MonadIO m => String -> (SendAPI :~> m) -> (SendAPI :~> m)
traceSendAPI msg f = wrapNT $ \ case
  (Sync v) -> do
          liftIO $ putStrLn $ msg ++ "--> " ++ LT.unpack (decodeUtf8 (encode v))
          r <- f # (Sync v)
          liftIO $ putStrLn $ msg ++ "<-- " ++ LT.unpack (decodeUtf8 (encode r))
          return r
  (Async v) -> do
          liftIO $ putStrLn $ msg ++ "--> " ++ LT.unpack (decodeUtf8 (encode v))
          () <- f # (Async v)
          liftIO $ putStrLn $ msg ++ "// No response"
          return ()

-- | A tracing natural transformation morphism over the Receive API.
traceSendAPI msg f = wrapNT $ \ case
  (Sync v) -> do
          liftIO $ putStrLn $ msg ++ "--> " ++ LT.unpack (decodeUtf8 (encode v))
          r <- f # (Sync v)
          liftIO $ putStrLn $ msg ++ "<-- " ++ LT.unpack (decodeUtf8 (encode r))
          return r
  (Async v) -> do
          liftIO $ putStrLn $ msg ++ "--> " ++ LT.unpack (decodeUtf8 (encode v))
          () <- f # (Async v)
          liftIO $ putStrLn $ msg ++ "// No response"
          return ()

-- | A tracing natural transformation morphism over the Receive API.