    {-# Language CPP #-}
    -- |
    -- Module      : Basement.Compat.NumLiteral
    -- License     : BSD-style
    -- Maintainer  : Foundation
    --
    -- Literal support for Integral and Fractional
    {-# LANGUAGE TypeSynonymInstances #-}
    {-# LANGUAGE FlexibleInstances #-}
    module Basement.Compat.NumLiteral
        ( Integral(..)
        , Fractional(..)
        , HasNegation(..)
        ) where

    import           Prelude (Int, Integer, Rational, Float, Double)
    import           Data.Word (Word8, Word16, Word32, Word64, Word)
    import           Data.Int (Int8, Int16, Int32, Int64)
    import           Basement.Compat.C.Types
    import qualified Prelude
    import           Basement.Compat.Natural
    import           Foreign.Ptr (IntPtr)

    -- | Integral Literal support
    --
    -- e.g. 123 :: Integer
    --      123 :: Word8
    class Integral a where
        fromInteger :: Integer -> a

    -- | Fractional Literal support
    --
    -- e.g. 1.2  :: Double
    --      0.03 :: Float
    class Fractional a where
        fromRational :: Rational -> a

    -- | Negation support
    --
    -- e.g. -(f x)
    class HasNegation a where
        negate :: a -> a

    instance Integral Integer where
        fromInteger a = a
    instance Integral Natural where
        fromInteger a = Prelude.fromInteger a
    instance Integral Int where
        fromInteger a = Prelude.fromInteger a
    instance Integral Word where
        fromInteger a = Prelude.fromInteger a
    instance Integral Word8 where
        fromInteger a = Prelude.fromInteger a
    instance Integral Word16 where
        fromInteger a = Prelude.fromInteger a
    instance Integral Word32 where
        fromInteger a = Prelude.fromInteger a
    instance Integral Word64 where
        fromInteger a = Prelude.fromInteger a
    instance Integral Int8 where
        fromInteger a = Prelude.fromInteger a
    instance Integral Int16 where
        fromInteger a = Prelude.fromInteger a
    instance Integral Int32 where
        fromInteger a = Prelude.fromInteger a
    instance Integral Int64 where
        fromInteger a = Prelude.fromInteger a
    instance Integral IntPtr where
        fromInteger a = Prelude.fromInteger a

    instance Integral Float where
        fromInteger a = Prelude.fromInteger a
    instance Integral Double where
        fromInteger a = Prelude.fromInteger a

    instance Integral CChar where
        fromInteger a = Prelude.fromInteger a
    instance Integral CSChar where
        fromInteger a = Prelude.fromInteger a
    instance Integral CUChar where
        fromInteger a = Prelude.fromInteger a
    instance Integral CShort where
        fromInteger a = Prelude.fromInteger a
    instance Integral CUShort where
        fromInteger a = Prelude.fromInteger a
    instance Integral CInt where
        fromInteger a = Prelude.fromInteger a
    instance Integral CUInt where
        fromInteger a = Prelude.fromInteger a
    instance Integral CLong where
        fromInteger a = Prelude.fromInteger a
    instance Integral CULong where
        fromInteger a = Prelude.fromInteger a
    instance Integral CPtrdiff where
        fromInteger a = Prelude.fromInteger a
    instance Integral CSize where
        fromInteger a = Prelude.fromInteger a
    instance Integral CWchar where
        fromInteger a = Prelude.fromInteger a
    instance Integral CSigAtomic where
        fromInteger a = Prelude.fromInteger a
    instance Integral CLLong where
        fromInteger a = Prelude.fromInteger a
    instance Integral CULLong where
        fromInteger a = Prelude.fromInteger a
    #if MIN_VERSION_base(4, 10, 0)
    instance Integral CBool where
        fromInteger a = Prelude.fromInteger a
    #endif
    instance Integral CIntPtr where
        fromInteger a = Prelude.fromInteger a
    instance Integral CUIntPtr where
        fromInteger a = Prelude.fromInteger a
    instance Integral CIntMax where
        fromInteger a = Prelude.fromInteger a
    instance Integral CUIntMax where
        fromInteger a = Prelude.fromInteger a
    instance Integral CClock where
        fromInteger a = Prelude.fromInteger a
    instance Integral CTime where
        fromInteger a = Prelude.fromInteger a
    instance Integral CUSeconds where
        fromInteger a = Prelude.fromInteger a
    instance Integral CSUSeconds where
        fromInteger a = Prelude.fromInteger a
    instance Integral COff where
        fromInteger a = Prelude.fromInteger a
    instance Integral CFloat where
        fromInteger a = Prelude.fromInteger a
    instance Integral CDouble where
        fromInteger a = Prelude.fromInteger a

    instance HasNegation Integer where
        negate = Prelude.negate
    instance HasNegation Int where
        negate = Prelude.negate
    instance HasNegation Int8 where
        negate = Prelude.negate
    instance HasNegation Int16 where
        negate = Prelude.negate
    instance HasNegation Int32 where
        negate = Prelude.negate
    instance HasNegation Int64 where
        negate = Prelude.negate
    instance HasNegation Word where
        negate = Prelude.negate
    instance HasNegation Word8 where
        negate = Prelude.negate
    instance HasNegation Word16 where
        negate = Prelude.negate
    instance HasNegation Word32 where
        negate = Prelude.negate
    instance HasNegation Word64 where
        negate = Prelude.negate

    instance HasNegation Float where
        negate = Prelude.negate
    instance HasNegation Double where
        negate = Prelude.negate

    instance HasNegation CChar where
        negate = Prelude.negate
    instance HasNegation CSChar where
        negate = Prelude.negate
    instance HasNegation CShort where
        negate = Prelude.negate
    instance HasNegation CInt where
        negate = Prelude.negate
    instance HasNegation CLong where
        negate = Prelude.negate
    instance HasNegation CPtrdiff where
        negate = Prelude.negate
    instance HasNegation CWchar where
        negate = Prelude.negate
    instance HasNegation CLLong where
        negate = Prelude.negate
    instance HasNegation CIntMax where
        negate = Prelude.negate

    instance HasNegation CFloat where
        negate = Prelude.negate
    instance HasNegation CDouble where
        negate = Prelude.negate

    instance Fractional Rational where
        fromRational a = Prelude.fromRational a
    instance Fractional Float where
        fromRational a = Prelude.fromRational a
    instance Fractional Double where
        fromRational a = Prelude.fromRational a

    instance Fractional CFloat where
        fromRational a = Prelude.fromRational a
    instance Fractional CDouble where
        fromRational a = Prelude.fromRational a