module Time where

import Control.Monad.IO.Class (MonadIO, liftIO)
import Data.Int (Int64)
import System.Clock

time :: MonadIO m => String -> m a -> m a
time s a = do
    begin <- liftIO $ getTime Monotonic
    ret <- a
    end <- ret `seq` liftIO (getTime Monotonic)
    liftIO $ putStrLn $ s ++ " took " ++ show (toMillis (end `dt` begin)) ++ "ms."
    return ret

dt :: TimeSpec -> TimeSpec -> TimeSpec
dt (TimeSpec s1 ns1) ts2@(TimeSpec s2 ns2)
    | ns1 < ns2 = dt (TimeSpec (s1 - 1) (ns1 + 10^(9 :: Int))) ts2
    | otherwise = TimeSpec (s1 - s2) (ns1 - ns2)

toMillis :: TimeSpec -> Int64
toMillis (TimeSpec sec ns) = (sec * 1000) + (ns `div` 1000000)
