GHC/Num.hs

    {-# LANGUAGE Trustworthy #-}
    {-# LANGUAGE CPP, NoImplicitPrelude, MagicHash, UnboxedTuples #-}
    {-# OPTIONS_HADDOCK hide #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  GHC.Num
    -- Copyright   :  (c) The University of Glasgow 1994-2002
    -- License     :  see libraries/base/LICENSE
    --
    -- Maintainer  :  cvs-ghc@haskell.org
    -- Stability   :  internal
    -- Portability :  non-portable (GHC Extensions)
    --
    -- The 'Num' class and the 'Integer' type.
    --
    -----------------------------------------------------------------------------

    module GHC.Num (module GHC.Num, module GHC.Integer, module GHC.Natural) where

    #include "MachDeps.h"

    import GHC.Base
    import GHC.Integer
    import GHC.Natural
    #if !defined(MIN_VERSION_integer_gmp)
    import {-# SOURCE #-} GHC.Exception.Type (underflowException)
    #endif

    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)@
    --
    -- 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
    -- '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 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

        {-# INLINE fromInteger #-}   -- Just to be sure!
        fromInteger i = I# (integerToInt i)

    -- | @since 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 2.01
    instance  Num Integer  where
        (+) = plusInteger
        (-) = minusInteger
        (*) = timesInteger
        negate         = negateInteger
        fromInteger x  =  x

        abs = absInteger
        signum = signumInteger

    #if defined(MIN_VERSION_integer_gmp)
    -- | Note that `Natural`'s 'Num' instance isn't a ring: no element but 0 has an
    -- additive inverse. It is a semiring though.
    --
    -- @since 4.8.0.0
    instance  Num Natural  where
        (+) = plusNatural
        (-) = minusNatural
        (*) = timesNatural
        negate      = negateNatural
        fromInteger = naturalFromInteger

        abs = id
        signum = signumNatural

    #else
    -- | Note that `Natural`'s 'Num' instance isn't a ring: no element but 0 has an
    -- additive inverse. It is a semiring though.
    --
    -- @since 4.8.0.0
    instance Num Natural where
      Natural n + Natural m = Natural (n + m)
      {-# INLINE (+) #-}
      Natural n * Natural m = Natural (n * m)
      {-# INLINE (*) #-}
      Natural n - Natural m
          | m > n     = raise# underflowException
          | otherwise = Natural (n - m)
      {-# INLINE (-) #-}
      abs (Natural n) = Natural n
      {-# INLINE abs #-}
      signum (Natural n) = Natural (signum n)
      {-# INLINE signum #-}
      fromInteger = naturalFromInteger
      {-# INLINE fromInteger #-}

    #endif