{-# OPTIONS_GHC -Wall -Werror #-}
module Data.SBV.Utils.TDiff
( Timing(..)
, showTDiff
)
where
import Data.Time (NominalDiffTime)
import Data.IORef (IORef)
import Data.List (intercalate)
import Data.Ratio
import GHC.Real (Ratio((:%)))
import Numeric (showFFloat)
data Timing = NoTiming | PrintTiming | SaveTiming (IORef NominalDiffTime)
showTDiff :: NominalDiffTime -> String
showTDiff :: NominalDiffTime -> String
showTDiff diff :: NominalDiffTime
diff
| Integer
denom Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
/= 1
= NominalDiffTime -> String
forall a. Show a => a -> String
show NominalDiffTime
diff
| Bool
True
= String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate ":" [String]
fields
where total, denom :: Integer
total :: Integer
total :% denom :: Integer
denom = (Integer
picoFactor Integer -> Integer -> Ratio Integer
forall a. Integral a => a -> a -> Ratio a
% 1) Ratio Integer -> Ratio Integer -> Ratio Integer
forall a. Num a => a -> a -> a
* NominalDiffTime -> Ratio Integer
forall a. Real a => a -> Ratio Integer
toRational NominalDiffTime
diff
picoFactor :: Integer
picoFactor :: Integer
picoFactor = (10 :: Integer) Integer -> Integer -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ (12 :: Integer)
[s2p :: Integer
s2p, m2s :: Integer
m2s, h2m :: Integer
h2m, d2h :: Integer
d2h] = Int -> [Integer] -> [Integer]
forall a. Int -> [a] -> [a]
drop 1 ([Integer] -> [Integer]) -> [Integer] -> [Integer]
forall a b. (a -> b) -> a -> b
$ (Integer -> Integer -> Integer)
-> Integer -> [Integer] -> [Integer]
forall b a. (b -> a -> b) -> b -> [a] -> [b]
scanl Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(*) 1 [Integer
picoFactor, 60, 60, 24]
(days :: Integer
days, days' :: Integer
days') = Integer
total Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
`divMod` Integer
d2h
(hours :: Integer
hours, hours' :: Integer
hours') = Integer
days' Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
`divMod` Integer
h2m
(minutes :: Integer
minutes, seconds' :: Integer
seconds') = Integer
hours' Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
`divMod` Integer
m2s
(seconds :: Integer
seconds, picos :: Integer
picos) = Integer
seconds' Integer -> Integer -> (Integer, Integer)
forall a. Integral a => a -> a -> (a, a)
`divMod` Integer
s2p
secondsPicos :: String
secondsPicos = Integer -> String
forall a. Show a => a -> String
show Integer
seconds
String -> String -> String
forall a. [a] -> [a] -> [a]
++ (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= '.') (Maybe Int -> Double -> String -> String
forall a. RealFloat a => Maybe Int -> a -> String -> String
showFFloat (Int -> Maybe Int
forall a. a -> Maybe a
Just 3) (Integer -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
picos Double -> Double -> Double
forall a. Num a => a -> a -> a
* (10Double -> Double -> Double
forall a. Floating a => a -> a -> a
**(-12) :: Double)) "s")
aboveSeconds :: [String]
aboveSeconds = ((Char, Integer) -> String) -> [(Char, Integer)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (\(t :: Char
t, v :: Integer
v) -> Integer -> String
forall a. Show a => a -> String
show Integer
v String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
t]) ([(Char, Integer)] -> [String]) -> [(Char, Integer)] -> [String]
forall a b. (a -> b) -> a -> b
$ ((Char, Integer) -> Bool) -> [(Char, Integer)] -> [(Char, Integer)]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (\p :: (Char, Integer)
p -> (Char, Integer) -> Integer
forall a b. (a, b) -> b
snd (Char, Integer)
p Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== 0) [('d', Integer
days), ('h', Integer
hours), ('m', Integer
minutes)]
fields :: [String]
fields = [String]
aboveSeconds [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String
secondsPicos]