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

    -- | This module provides compatibility instances and wrappers for the
    -- things that @thyme@ does differently from @time@, and allows it to be
    -- used as a drop-in replacement for the latter, with the exceptions noted
    -- below:
    --
    --   * When constructing an 'UTCTime' or 'UniversalTime', use 'mkUTCTime' or
    --   'mkModJulianDate' in place of @UTCTime@ or @ModJulianDate@.
    --
    --   * Instead of pattern matching on @UTCTime@, use 'unUTCTime' to get
    --   a 'UTCView', which has a constructor @UTCTime@ with the same fields.
    --   For @ModJulianDate@, use 'getModJulianDate'. @ViewPatterns@ may make
    --   the transition more seamless.
    --
    --   * Where a third party library uses @time@, you can use 'toThyme' and
    --   'fromThyme' to convert between the corresponding types.
    --
    --   * 'Year's are 'Int's, not 'Integer's: you may need 'fromIntegral'.
    --
    -- You shouldn't need to use @lens@ or @vector-space@ directly if you don't
    -- want to. However if you do use @vector-space@ and wish to avoid the
    -- 'RealFrac' instances for 'DiffTime' and 'NominalDiffTime', import
    -- "Data.Thyme.Time.Core" instead.
    --
    -- Anything else is probably not intentional, and you should either contact
    -- me via IRC or file an issue at <https://github.com/liyang/thyme/issues>.

    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 a :: Int64
    a + :: Micro -> Micro -> Micro
    + Micro b :: Int64
    b = Int64 -> Micro
    Micro (Int64
    a Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    + Int64
    b)
        Micro a :: Int64
    a - :: Micro -> Micro -> Micro
    - Micro b :: Int64
    b = Int64 -> Micro
    Micro (Int64
    a Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    - Int64
    b)
        Micro a :: Int64
    a * :: Micro -> Micro -> Micro
    * Micro b :: Int64
    b = Int64 -> Micro
    Micro (Int64 -> Int64 -> Int64
    forall a. Integral a => a -> a -> a
    quot Int64
    a 1000 Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    * Int64 -> Int64 -> Int64
    forall a. Integral a => a -> a -> a
    quot Int64
    b 1000)
        negate :: Micro -> Micro
    negate (Micro a :: Int64
    a) = Int64 -> Micro
    Micro (Int64 -> Int64
    forall a. Num a => a -> a
    negate Int64
    a)
        abs :: Micro -> Micro
    abs (Micro a :: Int64
    a) = Int64 -> Micro
    Micro (Int64 -> Int64
    forall a. Num a => a -> a
    abs Int64
    a)
        signum :: Micro -> Micro
    signum (Micro a :: Int64
    a) = Int64 -> Micro
    Micro (Int64 -> Int64
    forall a. Num a => a -> a
    signum Int64
    a Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    * 1000000)
        fromInteger :: Integer -> Micro
    fromInteger a :: Integer
    a = Int64 -> Micro
    Micro (Integer -> Int64
    forall a. Num a => Integer -> a
    fromInteger Integer
    a Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    * 1000000)

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

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

    instance RealFrac Micro where
        {-# INLINE properFraction #-}
        properFraction :: Micro -> (b, Micro)
    properFraction a :: Micro
    a = (Int64 -> b
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int64
    q, Micro
    r) where
            (q :: Int64
    q, r :: Micro
    r) = Micro -> Micro -> (Int64, Micro)
    microQuotRem Micro
    a (Int64 -> Micro
    Micro 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 #-}