    module System.TimeIt(timeIt, timeItShow, timeItNamed, timeItT) where
    import System.CPUTime
    import Text.Printf
    import Control.Monad.IO.Class (MonadIO(liftIO))

    -- | Wrap a 'MonadIO' computation so that it prints out the execution time.
    timeIt :: MonadIO m => m a -> m a
    timeIt :: m a -> m a
    timeIt = String -> m a -> m a
    forall (m :: * -> *) a. MonadIO m => String -> m a -> m a
    timeItNamed "CPU time"

    -- | Like 'timeIt', but uses the 'show' rendering of @a@ as label for the
    -- timing.
    --
    -- @since 2.0
    timeItShow :: (MonadIO m, Show a) => m a -> m a
    timeItShow :: m a -> m a
    timeItShow ioa :: m a
    ioa = do
        (t :: Double
    t, a :: a
    a) <- m a -> m (Double, a)
    forall (m :: * -> *) a. MonadIO m => m a -> m (Double, a)
    timeItT m a
    ioa
        IO () -> m ()
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $ String -> Double -> IO ()
    forall r. PrintfType r => String -> r
    printf (a -> String
    forall a. Show a => a -> String
    show a
    a String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ ": %6.2fs\n") Double
    t
        a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return a
    a

    -- | Like 'timeIt', but uses the 'String' as label for the timing.
    --
    -- @since 2.0
    timeItNamed :: MonadIO m => String -> m a -> m a
    timeItNamed :: String -> m a -> m a
    timeItNamed name :: String
    name ioa :: m a
    ioa = do
        (t :: Double
    t, a :: a
    a) <- m a -> m (Double, a)
    forall (m :: * -> *) a. MonadIO m => m a -> m (Double, a)
    timeItT m a
    ioa
        IO () -> m ()
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $ String -> Double -> IO ()
    forall r. PrintfType r => String -> r
    printf (String
    name String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ ": %6.2fs\n") Double
    t
        a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return a
    a

    -- | Wrap a 'MonadIO' computation so that it returns execution time in seconds,
    -- as well as the result value.
    timeItT :: MonadIO m => m a -> m (Double, a)
    timeItT :: m a -> m (Double, a)
    timeItT ioa :: m a
    ioa = do
        Integer
    t1 <- IO Integer -> m Integer
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO IO Integer
    getCPUTime
        a
    a <- m a
    ioa
        Integer
    t2 <- IO Integer -> m Integer
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO IO Integer
    getCPUTime
        let t :: Double
            t :: Double
    t = Integer -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Integer
    t2Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    -Integer
    t1) Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * 1e-12
        (Double, a) -> m (Double, a)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Double
    t, a
    a)