Hello, 

I want to write a timing method to test sub steps in my program.  I tested my timing method as follows:

=====
time.hs
=====

import Data.Time

time :: String -> IO a -> IO a
time str a = do
    start <- getCurrentTime
    v <- a
    end <- getCurrentTime
    let diff = diffUTCTime end  start
    putStrLn $ str ++ showNominalDiffTime (diff)
    return v

showNominalDiffTime :: NominalDiffTime -> String
showNominalDiffTime nTime = let timeString = show nTime in
                              take (length timeString - 1) timeString ++ " sec"

fun :: IO (Int, [Int])
fun = do
   i <- time "product: " $ return $! product [1..10000] -- testing strictness : evaluated
   j <- time "product list: " $ return $! map (\_ -> product [1..10000]) [1..3] -- testing strictness : not evaluated  List is in hnf
   return (i, j)

main =  fun

=====
In the shell
=====
$ time ./time
product: 0.001813 sec
product list: 0.000001 sec

real 0m0.006s
user 0m0.000s
sys 0m0.005s

Notice that the ($!) operation will reduce a term to head normal form (hnf), not normal form.
 
In the "product list" testing, the "complicated" map evaluation is reduced to a list of redex.  Therefore, the result does not reflect the time needed to get the final value.

How could I improve my timing method so that it will give the time to reduce a general expression to normal form?

Jiansen