withExecutorDriver :: ToExecutor a => a -> (ExecutorDriver -> IO b) -> IO b
withExecutorDriver e f = withExecutor e $ \executor -> do
  driver <- createDriver executor
  result <- f driver
  destroyDriver driver
  return result

-- | Callback interface to be implemented by frameworks' executors. Note
-- that only one callback will be invoked at a time, so it is not
-- recommended that you block within a callback because it may cause a
-- deadlock.
withExecutorDriver :: ToExecutor a => a -> (ExecutorDriver -> IO b) -> IO b
withExecutorDriver e f = withExecutor e $ \executor -> do
  driver <- createDriver executor
  result <- f driver
  destroyDriver driver
  return result

-- | Callback interface to be implemented by frameworks' executors. Note
-- that only one callback will be invoked at a time, so it is not
-- recommended that you block within a callback because it may cause a
-- deadlock.
withExecutorDriver e f = withExecutor e $ \executor -> do
  driver <- createDriver executor
  result <- f driver
  destroyDriver driver
  return result

-- | Callback interface to be implemented by frameworks' executors. Note
-- that only one callback will be invoked at a time, so it is not
-- recommended that you block within a callback because it may cause a
-- deadlock.