ghc-internal-9.1401.0: src/GHC/Internal/Num.hs
{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE CPP, NoImplicitPrelude, MagicHash, UnboxedTuples #-}
{-# OPTIONS_HADDOCK not-home #-}
-----------------------------------------------------------------------------
-- |
-- Module : GHC.Internal.Num
-- Copyright : (c) The University of Glasgow 1994-2002
-- License : see libraries/base/LICENSE
--
-- Maintainer : ghc-devs@haskell.org
-- Stability : internal
-- Portability : non-portable (GHC Extensions)
--
-- The 'Num' class and the 'Integer' type.
--
-----------------------------------------------------------------------------
module GHC.Internal.Num
( Num(..)
, subtract
, quotRemInteger
, module GHC.Internal.Bignum.Integer
, module GHC.Internal.Bignum.Natural
-- reexported for backward compatibility
, module GHC.Internal.Natural
, module GHC.Internal.Integer
)
where
#include "MachDeps.h"
import qualified GHC.Internal.Natural
import qualified GHC.Internal.Integer
import GHC.Internal.Base
import GHC.Internal.Bignum.Integer
import GHC.Internal.Bignum.Natural
infixl 7 *
infixl 6 +, -
default () -- Double isn't available yet,
-- and we shouldn't be using defaults anyway
-- | Basic numeric class.
--
-- The Haskell Report defines no laws for 'Num'. However, @('+')@ and @('*')@ are
-- customarily expected to define a ring and have the following properties:
--
-- [__Associativity of @('+')@__]: @(x + y) + z@ = @x + (y + z)@
-- [__Commutativity of @('+')@__]: @x + y@ = @y + x@
-- [__@'fromInteger' 0@ is the additive identity__]: @x + fromInteger 0@ = @x@
-- [__'negate' gives the additive inverse__]: @x + negate x@ = @fromInteger 0@
-- [__Associativity of @('*')@__]: @(x * y) * z@ = @x * (y * z)@
-- [__@'fromInteger' 1@ is the multiplicative identity__]:
-- @x * fromInteger 1@ = @x@ and @fromInteger 1 * x@ = @x@
-- [__Distributivity of @('*')@ with respect to @('+')@__]:
-- @a * (b + c)@ = @(a * b) + (a * c)@ and @(b + c) * a@ = @(b * a) + (c * a)@
-- [__Coherence with 'toInteger'__]: if the type also implements 'GHC.Real.Integral', then
-- 'fromInteger' is a left inverse for 'GHC.Internal.Real.toInteger', i.e. @fromInteger (toInteger i) == i@
--
-- Note that it /isn't/ customarily expected that a type instance of both 'Num'
-- and 'Ord' implement an ordered ring. Indeed, in @base@ only 'Integer' and
-- 'Data.Ratio.Rational' do.
class Num a where
{-# MINIMAL (+), (*), abs, signum, fromInteger, (negate | (-)) #-}
(+), (-), (*) :: a -> a -> a
-- | Unary negation.
negate :: a -> a
-- | Absolute value.
abs :: a -> a
-- | Sign of a number.
-- The functions 'abs' and 'signum' should satisfy the law:
--
-- > abs x * signum x == x
--
-- For real numbers, the 'signum' is either @-1@ (negative), @0@ (zero)
-- or @1@ (positive).
signum :: a -> a
-- | Conversion from an 'Integer'.
-- An integer literal represents the application of the function
-- 'fromInteger' to the appropriate value of type 'Integer',
-- so such literals have type @('Num' a) => a@.
fromInteger :: Integer -> a
{-# INLINE (-) #-}
{-# INLINE negate #-}
x - y = x + negate y
negate x = 0 - x
-- | the same as @'flip' ('-')@.
--
-- Because @-@ is treated specially in the Haskell grammar,
-- @(-@ /e/@)@ is not a section, but an application of prefix negation.
-- However, @('subtract'@ /exp/@)@ is equivalent to the disallowed section.
{-# INLINE subtract #-}
subtract :: (Num a) => a -> a -> a
subtract x y = y - x
-- | @since base-2.01
instance Num Int where
I# x + I# y = I# (x +# y)
I# x - I# y = I# (x -# y)
negate (I# x) = I# (negateInt# x)
I# x * I# y = I# (x *# y)
abs n = if n `geInt` 0 then n else negate n
signum n | n `ltInt` 0 = negate 1
| n `eqInt` 0 = 0
| otherwise = 1
fromInteger i = I# (integerToInt# i)
-- | @since base-2.01
instance Num Word where
(W# x#) + (W# y#) = W# (x# `plusWord#` y#)
(W# x#) - (W# y#) = W# (x# `minusWord#` y#)
(W# x#) * (W# y#) = W# (x# `timesWord#` y#)
negate (W# x#) = W# (int2Word# (negateInt# (word2Int# x#)))
abs x = x
signum 0 = 0
signum _ = 1
fromInteger i = W# (integerToWord# i)
-- | @since base-2.01
instance Num Integer where
(+) = integerAdd
(-) = integerSub
(*) = integerMul
negate = integerNegate
fromInteger i = i
abs = integerAbs
signum = integerSignum
-- | Note that `Natural`'s 'Num' instance isn't a ring: no element but 0 has an
-- additive inverse. It is a semiring though.
--
-- @since base-4.8.0.0
instance Num Natural where
(+) = naturalAdd
(-) = naturalSubThrow
(*) = naturalMul
negate = naturalNegate
fromInteger i = integerToNaturalThrow i
abs = id
signum = naturalSignum
{-# DEPRECATED quotRemInteger "Use integerQuotRem# instead" #-}
quotRemInteger :: Integer -> Integer -> (# Integer, Integer #)
quotRemInteger = integerQuotRem#