Built-in Natural literals in Core
[ghc.git] / libraries / base / GHC / Num.hs
1 {-# LANGUAGE Trustworthy #-}
2 {-# LANGUAGE CPP, NoImplicitPrelude, MagicHash, UnboxedTuples #-}
3 {-# OPTIONS_HADDOCK hide #-}
4
5 -----------------------------------------------------------------------------
6 -- |
7 -- Module : GHC.Num
8 -- Copyright : (c) The University of Glasgow 1994-2002
9 -- License : see libraries/base/LICENSE
10 --
11 -- Maintainer : cvs-ghc@haskell.org
12 -- Stability : internal
13 -- Portability : non-portable (GHC Extensions)
14 --
15 -- The 'Num' class and the 'Integer' type.
16 --
17 -----------------------------------------------------------------------------
18
19
20 module GHC.Num (module GHC.Num, module GHC.Integer, module GHC.Natural) where
21
22 #include "MachDeps.h"
23
24 import GHC.Base
25 import GHC.Integer
26 import GHC.Natural
27 #if !defined(MIN_VERSION_integer_gmp)
28 import {-# SOURCE #-} GHC.Exception.Type (underflowException)
29 #endif
30
31 infixl 7 *
32 infixl 6 +, -
33
34 default () -- Double isn't available yet,
35 -- and we shouldn't be using defaults anyway
36
37 -- | Basic numeric class.
38 class Num a where
39 {-# MINIMAL (+), (*), abs, signum, fromInteger, (negate | (-)) #-}
40
41 (+), (-), (*) :: a -> a -> a
42 -- | Unary negation.
43 negate :: a -> a
44 -- | Absolute value.
45 abs :: a -> a
46 -- | Sign of a number.
47 -- The functions 'abs' and 'signum' should satisfy the law:
48 --
49 -- > abs x * signum x == x
50 --
51 -- For real numbers, the 'signum' is either @-1@ (negative), @0@ (zero)
52 -- or @1@ (positive).
53 signum :: a -> a
54 -- | Conversion from an 'Integer'.
55 -- An integer literal represents the application of the function
56 -- 'fromInteger' to the appropriate value of type 'Integer',
57 -- so such literals have type @('Num' a) => a@.
58 fromInteger :: Integer -> a
59
60 {-# INLINE (-) #-}
61 {-# INLINE negate #-}
62 x - y = x + negate y
63 negate x = 0 - x
64
65 -- | the same as @'flip' ('-')@.
66 --
67 -- Because @-@ is treated specially in the Haskell grammar,
68 -- @(-@ /e/@)@ is not a section, but an application of prefix negation.
69 -- However, @('subtract'@ /exp/@)@ is equivalent to the disallowed section.
70 {-# INLINE subtract #-}
71 subtract :: (Num a) => a -> a -> a
72 subtract x y = y - x
73
74 -- | @since 2.01
75 instance Num Int where
76 I# x + I# y = I# (x +# y)
77 I# x - I# y = I# (x -# y)
78 negate (I# x) = I# (negateInt# x)
79 I# x * I# y = I# (x *# y)
80 abs n = if n `geInt` 0 then n else negate n
81
82 signum n | n `ltInt` 0 = negate 1
83 | n `eqInt` 0 = 0
84 | otherwise = 1
85
86 {-# INLINE fromInteger #-} -- Just to be sure!
87 fromInteger i = I# (integerToInt i)
88
89 -- | @since 2.01
90 instance Num Word where
91 (W# x#) + (W# y#) = W# (x# `plusWord#` y#)
92 (W# x#) - (W# y#) = W# (x# `minusWord#` y#)
93 (W# x#) * (W# y#) = W# (x# `timesWord#` y#)
94 negate (W# x#) = W# (int2Word# (negateInt# (word2Int# x#)))
95 abs x = x
96 signum 0 = 0
97 signum _ = 1
98 fromInteger i = W# (integerToWord i)
99
100 -- | @since 2.01
101 instance Num Integer where
102 (+) = plusInteger
103 (-) = minusInteger
104 (*) = timesInteger
105 negate = negateInteger
106 fromInteger x = x
107
108 abs = absInteger
109 signum = signumInteger
110
111 #if defined(MIN_VERSION_integer_gmp)
112 -- | @since 4.8.0.0
113 instance Num Natural where
114 (+) = plusNatural
115 (-) = minusNatural
116 (*) = timesNatural
117 negate = negateNatural
118 fromInteger = naturalFromInteger
119
120 abs = id
121 signum = signumNatural
122
123 #else
124 -- | @since 4.8.0.0
125 instance Num Natural where
126 Natural n + Natural m = Natural (n + m)
127 {-# INLINE (+) #-}
128 Natural n * Natural m = Natural (n * m)
129 {-# INLINE (*) #-}
130 Natural n - Natural m
131 | m > n = raise# underflowException
132 | otherwise = Natural (n - m)
133 {-# INLINE (-) #-}
134 abs (Natural n) = Natural n
135 {-# INLINE abs #-}
136 signum (Natural n) = Natural (signum n)
137 {-# INLINE signum #-}
138 fromInteger = naturalFromInteger
139 {-# INLINE fromInteger #-}
140
141 #endif