module System.Clock where
open import Level using (Level)
open import Data.Bool.Base
open import Data.Product
open import Data.Nat.Base using (ℕ; zero; suc; _+_; _∸_; _^_; _<ᵇ_)
open import Codata.IO
open import Function
open import Foreign.Haskell
open import System.Clock.Primitive as Prim
using (Clock ; Monotonic ; Realtime ; ProcessCPUTime
; ThreadCPUTime ; MonotonicRaw ; Boottime
; MonotonicCoarse ; RealtimeCoarse) public
record Time : Set where
constructor mkTime
field seconds : ℕ
nanoseconds : ℕ
open Time public
diff : Time → Time → Time
diff (mkTime ss sns) (mkTime es ens) =
if ens <ᵇ sns
then mkTime (es ∸ suc ss) ((1000000000 + ens) ∸ sns)
else mkTime (es ∸ ss) (ens ∸ sns)
getTime : ∀ {ℓ} → Clock → IO ℓ Time
getTime c = do
(a , b) ← lift (Prim.getTime c)
return $ mkTime a b
module _ {a ℓ} {A : Set a} {{_ : a ≤ˡ ℓ}} where
time : IO ℓ A → IO ℓ (A × Time)
time io = do
start ← getTime Realtime
a ← io
end ← getTime Realtime
return (a , diff start end)
time′ : IO ℓ A → IO ℓ Time
time′ io = proj₂ <$> time io
import Data.Nat.Show as ℕ
open import Data.Nat.DivMod
open import Data.Nat.Properties as ℕₚ
open import Data.Fin
open import Data.String.Base hiding (show)
open import Data.String.Extras
open import Relation.Nullary.Decidable
open import Relation.Binary.PropositionalEquality
show : Time → Fin 9 → String
show (mkTime s ns) prec = secs ++ "s" ++ padLeft '0' decimals nsecs where
decimals = toℕ prec
secs = ℕ.show s
nsecs = ℕ.show ((ns div (10 ^ (9 ∸ decimals)))
{exp-nz 10 (9 ∸ decimals)})
where
exp-nz : ∀ x n {x≠0 : False (x ℕₚ.≟ 0)} → False (x ^ n ℕₚ.≟ 0)
exp-nz x n {x≠0} = fromWitnessFalse (toWitnessFalse x≠0 ∘′ m^n≡0⇒m≡0 x n)