f2e0b5b159f20b217f0f62f1a2249387b58ffa2d
[ghc.git] / libraries / base / GHC / Enum.lhs
1 \begin{code}
2 {-# LANGUAGE Trustworthy #-}
3 {-# LANGUAGE NoImplicitPrelude, BangPatterns, MagicHash #-}
4 {-# OPTIONS_HADDOCK hide #-}
5
6 -----------------------------------------------------------------------------
7 -- |
8 -- Module      :  GHC.Enum
9 -- Copyright   :  (c) The University of Glasgow, 1992-2002
10 -- License     :  see libraries/base/LICENSE
11 -- 
12 -- Maintainer  :  cvs-ghc@haskell.org
13 -- Stability   :  internal
14 -- Portability :  non-portable (GHC extensions)
15 --
16 -- The 'Enum' and 'Bounded' classes.
17 -- 
18 -----------------------------------------------------------------------------
19
20 #include "MachDeps.h"
21
22 -- #hide
23 module GHC.Enum(
24         Bounded(..), Enum(..),
25         boundedEnumFrom, boundedEnumFromThen,
26         toEnumError, fromEnumError, succError, predError,
27
28         -- Instances for Bounded and Enum: (), Char, Int
29
30    ) where
31
32 import GHC.Base
33 import GHC.Char
34 import GHC.Integer
35 import GHC.Num
36 import GHC.Show
37 default ()              -- Double isn't available yet
38 \end{code}
39
40
41 %*********************************************************
42 %*                                                      *
43 \subsection{Class declarations}
44 %*                                                      *
45 %*********************************************************
46
47 \begin{code}
48 -- | The 'Bounded' class is used to name the upper and lower limits of a
49 -- type.  'Ord' is not a superclass of 'Bounded' since types that are not
50 -- totally ordered may also have upper and lower bounds.
51 --
52 -- The 'Bounded' class may be derived for any enumeration type;
53 -- 'minBound' is the first constructor listed in the @data@ declaration
54 -- and 'maxBound' is the last.
55 -- 'Bounded' may also be derived for single-constructor datatypes whose
56 -- constituent types are in 'Bounded'.
57
58 class  Bounded a  where
59     minBound, maxBound :: a
60
61 -- | Class 'Enum' defines operations on sequentially ordered types.
62 --
63 -- The @enumFrom@... methods are used in Haskell's translation of
64 -- arithmetic sequences.
65 --
66 -- Instances of 'Enum' may be derived for any enumeration type (types
67 -- whose constructors have no fields).  The nullary constructors are
68 -- assumed to be numbered left-to-right by 'fromEnum' from @0@ through @n-1@.
69 -- See Chapter 10 of the /Haskell Report/ for more details.
70 --  
71 -- For any type that is an instance of class 'Bounded' as well as 'Enum',
72 -- the following should hold:
73 --
74 -- * The calls @'succ' 'maxBound'@ and @'pred' 'minBound'@ should result in
75 --   a runtime error.
76 -- 
77 -- * 'fromEnum' and 'toEnum' should give a runtime error if the 
78 --   result value is not representable in the result type.
79 --   For example, @'toEnum' 7 :: 'Bool'@ is an error.
80 --
81 -- * 'enumFrom' and 'enumFromThen' should be defined with an implicit bound,
82 --   thus:
83 --
84 -- >    enumFrom     x   = enumFromTo     x maxBound
85 -- >    enumFromThen x y = enumFromThenTo x y bound
86 -- >      where
87 -- >        bound | fromEnum y >= fromEnum x = maxBound
88 -- >              | otherwise                = minBound
89 --
90 class  Enum a   where
91     -- | the successor of a value.  For numeric types, 'succ' adds 1.
92     succ                :: a -> a
93     -- | the predecessor of a value.  For numeric types, 'pred' subtracts 1.
94     pred                :: a -> a
95     -- | Convert from an 'Int'.
96     toEnum              :: Int -> a
97     -- | Convert to an 'Int'.
98     -- It is implementation-dependent what 'fromEnum' returns when
99     -- applied to a value that is too large to fit in an 'Int'.
100     fromEnum            :: a -> Int
101
102     -- | Used in Haskell's translation of @[n..]@.
103     enumFrom            :: a -> [a]
104     -- | Used in Haskell's translation of @[n,n'..]@.
105     enumFromThen        :: a -> a -> [a]
106     -- | Used in Haskell's translation of @[n..m]@.
107     enumFromTo          :: a -> a -> [a]
108     -- | Used in Haskell's translation of @[n,n'..m]@.
109     enumFromThenTo      :: a -> a -> a -> [a]
110
111     succ                   = toEnum . (+ 1)  . fromEnum
112     pred                   = toEnum . (subtract 1) . fromEnum
113     enumFrom x             = map toEnum [fromEnum x ..]
114     enumFromThen x y       = map toEnum [fromEnum x, fromEnum y ..]
115     enumFromTo x y         = map toEnum [fromEnum x .. fromEnum y]
116     enumFromThenTo x1 x2 y = map toEnum [fromEnum x1, fromEnum x2 .. fromEnum y]
117
118 -- Default methods for bounded enumerations
119 boundedEnumFrom :: (Enum a, Bounded a) => a -> [a]
120 boundedEnumFrom n = map toEnum [fromEnum n .. fromEnum (maxBound `asTypeOf` n)]
121
122 boundedEnumFromThen :: (Enum a, Bounded a) => a -> a -> [a]
123 boundedEnumFromThen n1 n2 
124   | i_n2 >= i_n1  = map toEnum [i_n1, i_n2 .. fromEnum (maxBound `asTypeOf` n1)]
125   | otherwise     = map toEnum [i_n1, i_n2 .. fromEnum (minBound `asTypeOf` n1)]
126   where
127     i_n1 = fromEnum n1
128     i_n2 = fromEnum n2
129 \end{code}
130
131 \begin{code}
132 ------------------------------------------------------------------------
133 -- Helper functions
134 ------------------------------------------------------------------------
135
136 {-# NOINLINE toEnumError #-}
137 toEnumError :: (Show a) => String -> Int -> (a,a) -> b
138 toEnumError inst_ty i bnds =
139     error $ "Enum.toEnum{" ++ inst_ty ++ "}: tag (" ++
140             show i ++
141             ") is outside of bounds " ++
142             show bnds
143
144 {-# NOINLINE fromEnumError #-}
145 fromEnumError :: (Show a) => String -> a -> b
146 fromEnumError inst_ty x =
147     error $ "Enum.fromEnum{" ++ inst_ty ++ "}: value (" ++
148             show x ++
149             ") is outside of Int's bounds " ++
150             show (minBound::Int, maxBound::Int)
151
152 {-# NOINLINE succError #-}
153 succError :: String -> a
154 succError inst_ty =
155     error $ "Enum.succ{" ++ inst_ty ++ "}: tried to take `succ' of maxBound"
156
157 {-# NOINLINE predError #-}
158 predError :: String -> a
159 predError inst_ty =
160     error $ "Enum.pred{" ++ inst_ty ++ "}: tried to take `pred' of minBound"
161 \end{code}
162
163
164 %*********************************************************
165 %*                                                      *
166 \subsection{Tuples}
167 %*                                                      *
168 %*********************************************************
169
170 \begin{code}
171 instance Bounded () where
172     minBound = ()
173     maxBound = ()
174
175 instance Enum () where
176     succ _      = error "Prelude.Enum.().succ: bad argument"
177     pred _      = error "Prelude.Enum.().pred: bad argument"
178
179     toEnum x | x == 0    = ()
180              | otherwise = error "Prelude.Enum.().toEnum: bad argument"
181
182     fromEnum () = 0
183     enumFrom ()         = [()]
184     enumFromThen () ()  = let many = ():many in many
185     enumFromTo () ()    = [()]
186     enumFromThenTo () () () = let many = ():many in many
187 \end{code}
188
189 \begin{code}
190 -- Report requires instances up to 15
191 instance (Bounded a, Bounded b) => Bounded (a,b) where
192    minBound = (minBound, minBound)
193    maxBound = (maxBound, maxBound)
194
195 instance (Bounded a, Bounded b, Bounded c) => Bounded (a,b,c) where
196    minBound = (minBound, minBound, minBound)
197    maxBound = (maxBound, maxBound, maxBound)
198
199 instance (Bounded a, Bounded b, Bounded c, Bounded d) => Bounded (a,b,c,d) where
200    minBound = (minBound, minBound, minBound, minBound)
201    maxBound = (maxBound, maxBound, maxBound, maxBound)
202
203 instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e) => Bounded (a,b,c,d,e) where
204    minBound = (minBound, minBound, minBound, minBound, minBound)
205    maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound)
206
207 instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f)
208         => Bounded (a,b,c,d,e,f) where
209    minBound = (minBound, minBound, minBound, minBound, minBound, minBound)
210    maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound)
211
212 instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g)
213         => Bounded (a,b,c,d,e,f,g) where
214    minBound = (minBound, minBound, minBound, minBound, minBound, minBound, minBound)
215    maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound)
216
217 instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g,
218           Bounded h)
219         => Bounded (a,b,c,d,e,f,g,h) where
220    minBound = (minBound, minBound, minBound, minBound, minBound, minBound, minBound, minBound)
221    maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound)
222
223 instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g,
224           Bounded h, Bounded i)
225         => Bounded (a,b,c,d,e,f,g,h,i) where
226    minBound = (minBound, minBound, minBound, minBound, minBound, minBound, minBound, minBound,
227                minBound)
228    maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound,
229                maxBound)
230
231 instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g,
232           Bounded h, Bounded i, Bounded j)
233         => Bounded (a,b,c,d,e,f,g,h,i,j) where
234    minBound = (minBound, minBound, minBound, minBound, minBound, minBound, minBound, minBound,
235                minBound, minBound)
236    maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound,
237                maxBound, maxBound)
238
239 instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g,
240           Bounded h, Bounded i, Bounded j, Bounded k)
241         => Bounded (a,b,c,d,e,f,g,h,i,j,k) where
242    minBound = (minBound, minBound, minBound, minBound, minBound, minBound, minBound, minBound,
243                minBound, minBound, minBound)
244    maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound,
245                maxBound, maxBound, maxBound)
246
247 instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g,
248           Bounded h, Bounded i, Bounded j, Bounded k, Bounded l)
249         => Bounded (a,b,c,d,e,f,g,h,i,j,k,l) where
250    minBound = (minBound, minBound, minBound, minBound, minBound, minBound, minBound, minBound,
251                minBound, minBound, minBound, minBound)
252    maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound,
253                maxBound, maxBound, maxBound, maxBound)
254
255 instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g,
256           Bounded h, Bounded i, Bounded j, Bounded k, Bounded l, Bounded m)
257         => Bounded (a,b,c,d,e,f,g,h,i,j,k,l,m) where
258    minBound = (minBound, minBound, minBound, minBound, minBound, minBound, minBound, minBound,
259                minBound, minBound, minBound, minBound, minBound)
260    maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound,
261                maxBound, maxBound, maxBound, maxBound, maxBound)
262
263 instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g,
264           Bounded h, Bounded i, Bounded j, Bounded k, Bounded l, Bounded m, Bounded n)
265         => Bounded (a,b,c,d,e,f,g,h,i,j,k,l,m,n) where
266    minBound = (minBound, minBound, minBound, minBound, minBound, minBound, minBound, minBound,
267                minBound, minBound, minBound, minBound, minBound, minBound)
268    maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound,
269                maxBound, maxBound, maxBound, maxBound, maxBound, maxBound)
270
271 instance (Bounded a, Bounded b, Bounded c, Bounded d, Bounded e, Bounded f, Bounded g,
272           Bounded h, Bounded i, Bounded j, Bounded k, Bounded l, Bounded m, Bounded n, Bounded o)
273         => Bounded (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) where
274    minBound = (minBound, minBound, minBound, minBound, minBound, minBound, minBound, minBound,
275                minBound, minBound, minBound, minBound, minBound, minBound, minBound)
276    maxBound = (maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound,
277                maxBound, maxBound, maxBound, maxBound, maxBound, maxBound, maxBound)
278 \end{code}
279
280
281 %*********************************************************
282 %*                                                      *
283 \subsection{Type @Bool@}
284 %*                                                      *
285 %*********************************************************
286
287 \begin{code}
288 instance Bounded Bool where
289   minBound = False
290   maxBound = True
291
292 instance Enum Bool where
293   succ False = True
294   succ True  = error "Prelude.Enum.Bool.succ: bad argument"
295
296   pred True  = False
297   pred False  = error "Prelude.Enum.Bool.pred: bad argument"
298
299   toEnum n | n == 0    = False
300            | n == 1    = True
301            | otherwise = error "Prelude.Enum.Bool.toEnum: bad argument"
302
303   fromEnum False = 0
304   fromEnum True  = 1
305
306   -- Use defaults for the rest
307   enumFrom     = boundedEnumFrom
308   enumFromThen = boundedEnumFromThen
309 \end{code}
310
311 %*********************************************************
312 %*                                                      *
313 \subsection{Type @Ordering@}
314 %*                                                      *
315 %*********************************************************
316
317 \begin{code}
318 instance Bounded Ordering where
319   minBound = LT
320   maxBound = GT
321
322 instance Enum Ordering where
323   succ LT = EQ
324   succ EQ = GT
325   succ GT = error "Prelude.Enum.Ordering.succ: bad argument"
326
327   pred GT = EQ
328   pred EQ = LT
329   pred LT = error "Prelude.Enum.Ordering.pred: bad argument"
330
331   toEnum n | n == 0 = LT
332            | n == 1 = EQ
333            | n == 2 = GT
334   toEnum _ = error "Prelude.Enum.Ordering.toEnum: bad argument"
335
336   fromEnum LT = 0
337   fromEnum EQ = 1
338   fromEnum GT = 2
339
340   -- Use defaults for the rest
341   enumFrom     = boundedEnumFrom
342   enumFromThen = boundedEnumFromThen
343 \end{code}
344
345 %*********************************************************
346 %*                                                      *
347 \subsection{Type @Char@}
348 %*                                                      *
349 %*********************************************************
350
351 \begin{code}
352 instance  Bounded Char  where
353     minBound =  '\0'
354     maxBound =  '\x10FFFF'
355
356 instance  Enum Char  where
357     succ (C# c#)
358        | not (ord# c# ==# 0x10FFFF#) = C# (chr# (ord# c# +# 1#))
359        | otherwise              = error ("Prelude.Enum.Char.succ: bad argument")
360     pred (C# c#)
361        | not (ord# c# ==# 0#)   = C# (chr# (ord# c# -# 1#))
362        | otherwise              = error ("Prelude.Enum.Char.pred: bad argument")
363
364     toEnum   = chr
365     fromEnum = ord
366
367     {-# INLINE enumFrom #-}
368     enumFrom (C# x) = eftChar (ord# x) 0x10FFFF#
369         -- Blarg: technically I guess enumFrom isn't strict!
370
371     {-# INLINE enumFromTo #-}
372     enumFromTo (C# x) (C# y) = eftChar (ord# x) (ord# y)
373     
374     {-# INLINE enumFromThen #-}
375     enumFromThen (C# x1) (C# x2) = efdChar (ord# x1) (ord# x2)
376     
377     {-# INLINE enumFromThenTo #-}
378     enumFromThenTo (C# x1) (C# x2) (C# y) = efdtChar (ord# x1) (ord# x2) (ord# y)
379
380 {-# RULES
381 "eftChar"       [~1] forall x y.        eftChar x y       = build (\c n -> eftCharFB c n x y)
382 "efdChar"       [~1] forall x1 x2.      efdChar x1 x2     = build (\ c n -> efdCharFB c n x1 x2)
383 "efdtChar"      [~1] forall x1 x2 l.    efdtChar x1 x2 l  = build (\ c n -> efdtCharFB c n x1 x2 l)
384 "eftCharList"   [1]  eftCharFB  (:) [] = eftChar
385 "efdCharList"   [1]  efdCharFB  (:) [] = efdChar
386 "efdtCharList"  [1]  efdtCharFB (:) [] = efdtChar
387  #-}
388
389
390 -- We can do better than for Ints because we don't
391 -- have hassles about arithmetic overflow at maxBound
392 {-# INLINE [0] eftCharFB #-}
393 eftCharFB :: (Char -> a -> a) -> a -> Int# -> Int# -> a
394 eftCharFB c n x0 y = go x0
395                  where
396                     go x | x ># y    = n
397                          | otherwise = C# (chr# x) `c` go (x +# 1#)
398
399 {-# NOINLINE [1] eftChar #-}
400 eftChar :: Int# -> Int# -> String
401 eftChar x y | x ># y    = []
402             | otherwise = C# (chr# x) : eftChar (x +# 1#) y
403
404
405 -- For enumFromThenTo we give up on inlining
406 {-# NOINLINE [0] efdCharFB #-}
407 efdCharFB :: (Char -> a -> a) -> a -> Int# -> Int# -> a
408 efdCharFB c n x1 x2
409   | delta >=# 0# = go_up_char_fb c n x1 delta 0x10FFFF#
410   | otherwise    = go_dn_char_fb c n x1 delta 0#
411   where
412     !delta = x2 -# x1
413
414 {-# NOINLINE [1] efdChar #-}
415 efdChar :: Int# -> Int# -> String
416 efdChar x1 x2
417   | delta >=# 0# = go_up_char_list x1 delta 0x10FFFF#
418   | otherwise    = go_dn_char_list x1 delta 0#
419   where
420     !delta = x2 -# x1
421
422 {-# NOINLINE [0] efdtCharFB #-}
423 efdtCharFB :: (Char -> a -> a) -> a -> Int# -> Int# -> Int# -> a
424 efdtCharFB c n x1 x2 lim
425   | delta >=# 0# = go_up_char_fb c n x1 delta lim
426   | otherwise    = go_dn_char_fb c n x1 delta lim
427   where
428     !delta = x2 -# x1
429
430 {-# NOINLINE [1] efdtChar #-}
431 efdtChar :: Int# -> Int# -> Int# -> String
432 efdtChar x1 x2 lim
433   | delta >=# 0# = go_up_char_list x1 delta lim
434   | otherwise    = go_dn_char_list x1 delta lim
435   where
436     !delta = x2 -# x1
437
438 go_up_char_fb :: (Char -> a -> a) -> a -> Int# -> Int# -> Int# -> a
439 go_up_char_fb c n x0 delta lim
440   = go_up x0
441   where
442     go_up x | x ># lim  = n
443             | otherwise = C# (chr# x) `c` go_up (x +# delta)
444
445 go_dn_char_fb :: (Char -> a -> a) -> a -> Int# -> Int# -> Int# -> a
446 go_dn_char_fb c n x0 delta lim
447   = go_dn x0
448   where
449     go_dn x | x <# lim  = n
450             | otherwise = C# (chr# x) `c` go_dn (x +# delta)
451
452 go_up_char_list :: Int# -> Int# -> Int# -> String
453 go_up_char_list x0 delta lim
454   = go_up x0
455   where
456     go_up x | x ># lim  = []
457             | otherwise = C# (chr# x) : go_up (x +# delta)
458
459 go_dn_char_list :: Int# -> Int# -> Int# -> String
460 go_dn_char_list x0 delta lim
461   = go_dn x0
462   where
463     go_dn x | x <# lim  = []
464             | otherwise = C# (chr# x) : go_dn (x +# delta)
465 \end{code}
466
467
468 %*********************************************************
469 %*                                                      *
470 \subsection{Type @Int@}
471 %*                                                      *
472 %*********************************************************
473
474 Be careful about these instances.  
475         (a) remember that you have to count down as well as up e.g. [13,12..0]
476         (b) be careful of Int overflow
477         (c) remember that Int is bounded, so [1..] terminates at maxInt
478
479 \begin{code}
480 instance  Bounded Int where
481     minBound =  minInt
482     maxBound =  maxInt
483
484 instance  Enum Int  where
485     succ x  
486        | x == maxBound  = error "Prelude.Enum.succ{Int}: tried to take `succ' of maxBound"
487        | otherwise      = x + 1
488     pred x
489        | x == minBound  = error "Prelude.Enum.pred{Int}: tried to take `pred' of minBound"
490        | otherwise      = x - 1
491
492     toEnum   x = x
493     fromEnum x = x
494
495     {-# INLINE enumFrom #-}
496     enumFrom (I# x) = eftInt x maxInt#
497         where !(I# maxInt#) = maxInt
498         -- Blarg: technically I guess enumFrom isn't strict!
499
500     {-# INLINE enumFromTo #-}
501     enumFromTo (I# x) (I# y) = eftInt x y
502
503     {-# INLINE enumFromThen #-}
504     enumFromThen (I# x1) (I# x2) = efdInt x1 x2
505
506     {-# INLINE enumFromThenTo #-}
507     enumFromThenTo (I# x1) (I# x2) (I# y) = efdtInt x1 x2 y
508
509
510 -----------------------------------------------------
511 -- eftInt and eftIntFB deal with [a..b], which is the 
512 -- most common form, so we take a lot of care
513 -- In particular, we have rules for deforestation
514
515 {-# RULES
516 "eftInt"        [~1] forall x y. eftInt x y = build (\ c n -> eftIntFB c n x y)
517 "eftIntList"    [1] eftIntFB  (:) [] = eftInt
518  #-}
519
520 {-# NOINLINE [1] eftInt #-}
521 eftInt :: Int# -> Int# -> [Int]
522 -- [x1..x2]
523 eftInt x0 y | x0 ># y    = []
524             | otherwise = go x0
525                where
526                  go x = I# x : if x ==# y then [] else go (x +# 1#)
527
528 {-# INLINE [0] eftIntFB #-}
529 eftIntFB :: (Int -> r -> r) -> r -> Int# -> Int# -> r
530 eftIntFB c n x0 y | x0 ># y    = n        
531                   | otherwise = go x0
532                  where
533                    go x = I# x `c` if x ==# y then n else go (x +# 1#)
534                         -- Watch out for y=maxBound; hence ==, not >
535         -- Be very careful not to have more than one "c"
536         -- so that when eftInfFB is inlined we can inline
537         -- whatever is bound to "c"
538
539
540 -----------------------------------------------------
541 -- efdInt and efdtInt deal with [a,b..] and [a,b..c].
542 -- The code is more complicated because of worries about Int overflow.
543
544 {-# RULES
545 "efdtInt"       [~1] forall x1 x2 y.
546                      efdtInt x1 x2 y = build (\ c n -> efdtIntFB c n x1 x2 y)
547 "efdtIntUpList" [1]  efdtIntFB (:) [] = efdtInt
548  #-}
549
550 efdInt :: Int# -> Int# -> [Int]
551 -- [x1,x2..maxInt]
552 efdInt x1 x2 
553  | x2 >=# x1 = case maxInt of I# y -> efdtIntUp x1 x2 y
554  | otherwise = case minInt of I# y -> efdtIntDn x1 x2 y
555
556 {-# NOINLINE [1] efdtInt #-}
557 efdtInt :: Int# -> Int# -> Int# -> [Int]
558 -- [x1,x2..y]
559 efdtInt x1 x2 y
560  | x2 >=# x1 = efdtIntUp x1 x2 y
561  | otherwise = efdtIntDn x1 x2 y
562
563 {-# INLINE [0] efdtIntFB #-}
564 efdtIntFB :: (Int -> r -> r) -> r -> Int# -> Int# -> Int# -> r
565 efdtIntFB c n x1 x2 y
566  | x2 >=# x1  = efdtIntUpFB c n x1 x2 y
567  | otherwise  = efdtIntDnFB c n x1 x2 y
568
569 -- Requires x2 >= x1
570 efdtIntUp :: Int# -> Int# -> Int# -> [Int]
571 efdtIntUp x1 x2 y    -- Be careful about overflow!
572  | y <# x2   = if y <# x1 then [] else [I# x1]
573  | otherwise = -- Common case: x1 <= x2 <= y
574                let !delta = x2 -# x1 -- >= 0
575                    !y' = y -# delta  -- x1 <= y' <= y; hence y' is representable
576
577                    -- Invariant: x <= y
578                    -- Note that: z <= y' => z + delta won't overflow
579                    -- so we are guaranteed not to overflow if/when we recurse
580                    go_up x | x ># y'  = [I# x]
581                            | otherwise = I# x : go_up (x +# delta)
582                in I# x1 : go_up x2
583
584 -- Requires x2 >= x1
585 efdtIntUpFB :: (Int -> r -> r) -> r -> Int# -> Int# -> Int# -> r
586 efdtIntUpFB c n x1 x2 y    -- Be careful about overflow!
587  | y <# x2   = if y <# x1 then n else I# x1 `c` n
588  | otherwise = -- Common case: x1 <= x2 <= y
589                let !delta = x2 -# x1 -- >= 0
590                    !y' = y -# delta  -- x1 <= y' <= y; hence y' is representable
591
592                    -- Invariant: x <= y
593                    -- Note that: z <= y' => z + delta won't overflow
594                    -- so we are guaranteed not to overflow if/when we recurse
595                    go_up x | x ># y'   = I# x `c` n
596                            | otherwise = I# x `c` go_up (x +# delta)
597                in I# x1 `c` go_up x2
598
599 -- Requires x2 <= x1
600 efdtIntDn :: Int# -> Int# -> Int# -> [Int]
601 efdtIntDn x1 x2 y    -- Be careful about underflow!
602  | y ># x2   = if y ># x1 then [] else [I# x1]
603  | otherwise = -- Common case: x1 >= x2 >= y
604                let !delta = x2 -# x1 -- <= 0
605                    !y' = y -# delta  -- y <= y' <= x1; hence y' is representable
606
607                    -- Invariant: x >= y
608                    -- Note that: z >= y' => z + delta won't underflow
609                    -- so we are guaranteed not to underflow if/when we recurse
610                    go_dn x | x <# y'  = [I# x]
611                            | otherwise = I# x : go_dn (x +# delta)
612    in I# x1 : go_dn x2
613
614 -- Requires x2 <= x1
615 efdtIntDnFB :: (Int -> r -> r) -> r -> Int# -> Int# -> Int# -> r
616 efdtIntDnFB c n x1 x2 y    -- Be careful about underflow!
617  | y ># x2 = if y ># x1 then n else I# x1 `c` n
618  | otherwise = -- Common case: x1 >= x2 >= y
619                let !delta = x2 -# x1 -- <= 0
620                    !y' = y -# delta  -- y <= y' <= x1; hence y' is representable
621
622                    -- Invariant: x >= y
623                    -- Note that: z >= y' => z + delta won't underflow
624                    -- so we are guaranteed not to underflow if/when we recurse
625                    go_dn x | x <# y'   = I# x `c` n
626                            | otherwise = I# x `c` go_dn (x +# delta)
627                in I# x1 `c` go_dn x2
628 \end{code}
629
630
631 %*********************************************************
632 %*                                                      *
633 \subsection{Type @Word@}
634 %*                                                      *
635 %*********************************************************
636
637 \begin{code}
638 instance Bounded Word where
639     minBound = 0
640
641     -- use unboxed literals for maxBound, because GHC doesn't optimise
642     -- (fromInteger 0xffffffff :: Word).
643 #if WORD_SIZE_IN_BITS == 32
644     maxBound = W# (int2Word# 0xFFFFFFFF#)
645 #elif WORD_SIZE_IN_BITS == 64
646     maxBound = W# (int2Word# 0xFFFFFFFFFFFFFFFF#)
647 #else
648 #error Unhandled value for WORD_SIZE_IN_BITS
649 #endif
650 \end{code}
651
652
653 %*********************************************************
654 %*                                                      *
655 \subsection{The @Integer@ instance for @Enum@}
656 %*                                                      *
657 %*********************************************************
658
659 \begin{code}
660 instance  Enum Integer  where
661     succ x               = x + 1
662     pred x               = x - 1
663     toEnum (I# n)        = smallInteger n
664     fromEnum n           = I# (integerToInt n)
665
666     {-# INLINE enumFrom #-}
667     {-# INLINE enumFromThen #-}
668     {-# INLINE enumFromTo #-}
669     {-# INLINE enumFromThenTo #-}
670     enumFrom x             = enumDeltaInteger  x 1
671     enumFromThen x y       = enumDeltaInteger  x (y-x)
672     enumFromTo x lim       = enumDeltaToInteger x 1     lim
673     enumFromThenTo x y lim = enumDeltaToInteger x (y-x) lim
674
675 {-# RULES
676 "enumDeltaInteger"      [~1] forall x y.  enumDeltaInteger x y     = build (\c _ -> enumDeltaIntegerFB c x y)
677 "efdtInteger"           [~1] forall x y l.enumDeltaToInteger x y l = build (\c n -> enumDeltaToIntegerFB c n x y l)
678 "enumDeltaInteger"      [1] enumDeltaIntegerFB   (:)    = enumDeltaInteger
679 "enumDeltaToInteger"    [1] enumDeltaToIntegerFB (:) [] = enumDeltaToInteger
680  #-}
681
682 {-# NOINLINE [0] enumDeltaIntegerFB #-}
683 enumDeltaIntegerFB :: (Integer -> b -> b) -> Integer -> Integer -> b
684 enumDeltaIntegerFB c x d = x `seq` (x `c` enumDeltaIntegerFB c (x+d) d)
685
686 {-# NOINLINE [1] enumDeltaInteger #-}
687 enumDeltaInteger :: Integer -> Integer -> [Integer]
688 enumDeltaInteger x d = x `seq` (x : enumDeltaInteger (x+d) d)
689 -- strict accumulator, so
690 --     head (drop 1000000 [1 .. ]
691 -- works
692
693 {-# NOINLINE [0] enumDeltaToIntegerFB #-}
694 -- Don't inline this until RULE "enumDeltaToInteger" has had a chance to fire
695 enumDeltaToIntegerFB :: (Integer -> a -> a) -> a
696                      -> Integer -> Integer -> Integer -> a
697 enumDeltaToIntegerFB c n x delta lim
698   | delta >= 0 = up_fb c n x delta lim
699   | otherwise  = dn_fb c n x delta lim
700
701 {-# NOINLINE [1] enumDeltaToInteger #-}
702 enumDeltaToInteger :: Integer -> Integer -> Integer -> [Integer]
703 enumDeltaToInteger x delta lim
704   | delta >= 0 = up_list x delta lim
705   | otherwise  = dn_list x delta lim
706
707 up_fb :: (Integer -> a -> a) -> a -> Integer -> Integer -> Integer -> a
708 up_fb c n x0 delta lim = go (x0 :: Integer)
709                       where
710                         go x | x > lim   = n
711                              | otherwise = x `c` go (x+delta)
712 dn_fb :: (Integer -> a -> a) -> a -> Integer -> Integer -> Integer -> a
713 dn_fb c n x0 delta lim = go (x0 :: Integer)
714                       where
715                         go x | x < lim   = n
716                              | otherwise = x `c` go (x+delta)
717
718 up_list :: Integer -> Integer -> Integer -> [Integer]
719 up_list x0 delta lim = go (x0 :: Integer)
720                     where
721                         go x | x > lim   = []
722                              | otherwise = x : go (x+delta)
723 dn_list :: Integer -> Integer -> Integer -> [Integer]
724 dn_list x0 delta lim = go (x0 :: Integer)
725                     where
726                         go x | x < lim   = []
727                              | otherwise = x : go (x+delta)
728 \end{code}
729