{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

-- | This module provides 'Num', 'Real', 'Fractional', and 'RealFrac'
-- instances for 'DiffTime' and 'NominalDiffTime'.
module Data.Thyme.Time
    ( module Data.Thyme.Time.Core
    {- instance RealFrac {,Nominal}DiffTime -}
    ) where

import Prelude
import Data.Thyme.Internal.Micro
import Data.Ratio
import Data.Thyme
import Data.Thyme.Clock.Internal
import Data.Thyme.Time.Core

instance Num Micro where
    {-# INLINE (+) #-}
    {-# INLINE (-) #-}
    {-# INLINE (*) #-}
    {-# INLINE negate #-}
    {-# INLINE abs #-}
    {-# INLINE signum #-}
    {-# INLINE fromInteger #-}
    Micro Int64
a + :: Micro -> Micro -> Micro
+ Micro Int64
b = Int64 -> Micro
Micro (Int64
a forall a. Num a => a -> a -> a
+ Int64
b)
    Micro Int64
a - :: Micro -> Micro -> Micro
- Micro Int64
b = Int64 -> Micro
Micro (Int64
a forall a. Num a => a -> a -> a
- Int64
b)
    Micro Int64
a * :: Micro -> Micro -> Micro
* Micro Int64
b = Int64 -> Micro
Micro (forall a. Integral a => a -> a -> a
quot Int64
a Int64
1000 forall a. Num a => a -> a -> a
* forall a. Integral a => a -> a -> a
quot Int64
b Int64
1000)
    negate :: Micro -> Micro
negate (Micro Int64
a) = Int64 -> Micro
Micro (forall a. Num a => a -> a
negate Int64
a)
    abs :: Micro -> Micro
abs (Micro Int64
a) = Int64 -> Micro
Micro (forall a. Num a => a -> a
abs Int64
a)
    signum :: Micro -> Micro
signum (Micro Int64
a) = Int64 -> Micro
Micro (forall a. Num a => a -> a
signum Int64
a forall a. Num a => a -> a -> a
* Int64
1000000)
    fromInteger :: Integer -> Micro
fromInteger Integer
a = Int64 -> Micro
Micro (forall a. Num a => Integer -> a
fromInteger Integer
a forall a. Num a => a -> a -> a
* Int64
1000000)

instance Real Micro where
    {-# INLINE toRational #-}
    toRational :: Micro -> Rational
toRational (Micro Int64
a) = forall a. Integral a => a -> Integer
toInteger Int64
a forall a. Integral a => a -> a -> Ratio a
% Integer
1000000

instance Fractional Micro where
    {-# INLINE (/) #-}
    {-# INLINE recip #-}
    {-# INLINE fromRational #-}
    Micro Int64
a / :: Micro -> Micro -> Micro
/ Micro Int64
b = Int64 -> Micro
Micro (forall a. Integral a => a -> a -> a
quot (Int64
a forall a. Num a => a -> a -> a
* Int64
1000) (Int64
b forall a. Integral a => a -> a -> a
`quot` Int64
1000))
    recip :: Micro -> Micro
recip (Micro Int64
a) = Int64 -> Micro
Micro (forall a. Integral a => a -> a -> a
quot Int64
1000000 Int64
a)
    fromRational :: Rational -> Micro
fromRational Rational
r = Int64 -> Micro
Micro (forall a b. (RealFrac a, Integral b) => a -> b
round forall a b. (a -> b) -> a -> b
$ Rational
r forall a. Num a => a -> a -> a
* Rational
1000000)

instance RealFrac Micro where
    {-# INLINE properFraction #-}
    properFraction :: forall b. Integral b => Micro -> (b, Micro)
properFraction Micro
a = (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64
q, Micro
r) where
        (Int64
q, Micro
r) = Micro -> Micro -> (Int64, Micro)
microQuotRem Micro
a (Int64 -> Micro
Micro Int64
1000000)

deriving instance Num DiffTime
deriving instance Real DiffTime
deriving instance Fractional DiffTime
deriving instance RealFrac DiffTime

deriving instance Num NominalDiffTime
deriving instance Real NominalDiffTime
deriving instance Fractional NominalDiffTime
deriving instance RealFrac NominalDiffTime

{-# RULES

"realToFrac/DiffTime-NominalDiffTime"
    realToFrac = \ (DiffTime d) -> NominalDiffTime d
"realToFrac/NominalDiffTime-DiffTime"
    realToFrac = \ (NominalDiffTime d) -> DiffTime d

"realToFrac/DiffTime-Fractional"
    realToFrac = toSeconds :: (Fractional n) => DiffTime -> n
"realToFrac/NominalDiffTime-Fractional"
    realToFrac = toSeconds :: (Fractional n) => NominalDiffTime -> n

"realToFrac/Real-DiffTime"
    realToFrac = fromSeconds :: (Real n) => n -> DiffTime
"realToFrac/Real-NominalDiffTime"
    realToFrac = fromSeconds :: (Real n) => n -> NominalDiffTime #-}