-------------------------------------------------------------------------------

-- | Measure how long action took, in seconds along with its result
time :: MonadIO m => m a -> m (Double, a)
time act = do
  start <- liftIO getTime
  !result <- act
  end <- liftIO getTime
  let !delta = end - start
  return (delta, result)

-- | Measure how long action took, even if they fail
time :: MonadIO m => m a -> m (Double, a)
time act = do
  start <- liftIO getTime
  !result <- act
  end <- liftIO getTime
  let !delta = end - start
  return (delta, result)

-- | Measure how long action took, even if they fail
time act = do
  start <- liftIO getTime
  !result <- act
  end <- liftIO getTime
  let !delta = end - start
  return (delta, result)

-- | Measure how long action took, even if they fail