2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[PrelBounded]{Module @PrelBounded@}
6 Instances of Bounded for various datatypes.
9 {-# OPTIONS -fno-implicit-prelude #-}
12 Bounded(..), Enum(..),
13 enumFromBounded, enumFromThenBounded,
15 -- Instances for Bounded and Eum: (), Char, Int
19 import {-# SOURCE #-} PrelErr ( error )
21 import PrelTup () -- To make sure we look for the .hi file
25 %*********************************************************
27 \subsection{Class declarations}
29 %*********************************************************
33 minBound, maxBound :: a
39 enumFrom :: a -> [a] -- [n..]
40 enumFromThen :: a -> a -> [a] -- [n,n'..]
41 enumFromTo :: a -> a -> [a] -- [n..m]
42 enumFromThenTo :: a -> a -> a -> [a] -- [n,n'..m]
44 succ = toEnum . (`plusInt` oneInt) . fromEnum
45 pred = toEnum . (`minusInt` oneInt) . fromEnum
46 enumFromTo n m = map toEnum [fromEnum n .. fromEnum m]
47 enumFromThenTo n1 n2 m = map toEnum [fromEnum n1, fromEnum n2 .. fromEnum m]
49 -- Default methods for bounded enumerations
50 enumFromBounded :: (Enum a, Bounded a) => a -> [a]
51 enumFromBounded n = enumFromTo n maxBound
53 enumFromThenBounded :: (Enum a, Bounded a) => a -> a -> [a]
54 enumFromThenBounded n1 n2 = enumFromThenTo n1 n2 maxBound
58 %*********************************************************
62 %*********************************************************
65 instance Bounded () where
69 instance Enum () where
70 succ x = error "Prelude.Enum.().succ: bad argment"
71 pred x = error "Prelude.Enum.().pred: bad argument"
73 toEnum x | x == zeroInt = ()
74 | otherwise = error "Prelude.Enum.().toEnum: bad argument"
78 enumFromThen () () = [()]
79 enumFromTo () () = [()]
80 enumFromThenTo () () () = [()]
84 instance (Bounded a, Bounded b) => Bounded (a,b) where
85 minBound = (minBound, minBound)
86 maxBound = (maxBound, maxBound)
88 instance (Bounded a, Bounded b, Bounded c) => Bounded (a,b,c) where
89 minBound = (minBound, minBound, minBound)
90 maxBound = (maxBound, maxBound, maxBound)
92 instance (Bounded a, Bounded b, Bounded c, Bounded d) => Bounded (a,b,c,d) where
93 minBound = (minBound, minBound, minBound, minBound)
94 maxBound = (maxBound, maxBound, maxBound, maxBound)
98 %*********************************************************
100 \subsection{Type @Bool@}
102 %*********************************************************
105 instance Bounded Bool where
109 instance Enum Bool where
111 succ True = error "Prelude.Enum.Bool.succ: bad argment"
114 pred False = error "Prelude.Enum.Bool.pred: bad argment"
116 toEnum n | n == zeroInt = False
118 | otherwise = error "Prelude.Enum.Bool.toEnum: bad argment"
120 fromEnum False = zeroInt
121 fromEnum True = oneInt
123 -- Use defaults for the rest
124 enumFrom = enumFromBounded
125 enumFromThen = enumFromThenBounded
128 %*********************************************************
130 \subsection{Type @Ordering@}
132 %*********************************************************
135 instance Bounded Ordering where
139 instance Enum Ordering where
142 succ GT = error "Prelude.Enum.Ordering.succ: bad argment"
146 pred LT = error "Prelude.Enum.Ordering.pred: bad argment"
148 toEnum n | n == zeroInt = LT
151 toEnum n = error "Prelude.Enum.Ordering.toEnum: bad argment"
153 fromEnum LT = zeroInt
157 -- Use defaults for the rest
158 enumFrom = enumFromBounded
159 enumFromThen = enumFromThenBounded
162 %*********************************************************
164 \subsection{Type @Char@}
166 %*********************************************************
169 instance Bounded Char where
173 instance Enum Char where
175 | not (ord# c# ==# 255#) = C# (chr# (ord# c# +# 1#))
176 | otherwise = error ("Prelude.Enum.Char.succ: bad argument")
178 | not (ord# c# ==# 0#) = C# (chr# (ord# c# -# 1#))
179 | otherwise = error ("Prelude.Enum.Char.pred: bad argument")
184 {-# INLINE enumFrom #-}
185 enumFrom (C# x) = build (\ c n -> eftCharFB c n (ord# x) 255#)
186 -- Blarg: technically I guess enumFrom isn't strict!
188 {-# INLINE enumFromTo #-}
189 enumFromTo (C# x) (C# y) = build (\ c n -> eftCharFB c n (ord# x) (ord# y))
191 {-# INLINE enumFromThen #-}
192 enumFromThen (C# x1) (C# x2) = build (\ c n -> efdtCharFB c n (ord# x1) (ord# x2) 255#)
194 {-# INLINE enumFromThenTo #-}
195 enumFromThenTo (C# x1) (C# x2) (C# y) = build (\ c n -> efdtCharFB c n (ord# x1) (ord# x2) (ord# y))
197 -- We can do better than for Ints because we don't
198 -- have hassles about arithmetic overflow at maxBound
199 {-# INLINE eftCharFB #-}
200 eftCharFB c n x y = go x
203 | otherwise = C# (chr# x) `c` go (x +# 1#)
205 eftCharList x y | x ># y = []
206 | otherwise = C# (chr# x) : eftCharList (x +# 1#) y
209 -- For enumFromThenTo we give up on inlining
210 efdtCharFB c n x1 x2 y
211 | delta >=# 0# = go_up x1
212 | otherwise = go_dn x1
216 | otherwise = C# (chr# x) `c` go_up (x +# delta)
218 | otherwise = C# (chr# x) `c` go_dn (x +# delta)
221 | delta >=# 0# = go_up x1
222 | otherwise = go_dn x1
225 go_up x | x ># y = []
226 | otherwise = C# (chr# x) : go_up (x +# delta)
227 go_dn x | x <# y = []
228 | otherwise = C# (chr# x) : go_dn (x +# delta)
232 "eftCharList" eftCharFB (:) [] = eftCharList
233 "efdtCharList" efdtCharFB (:) [] = efdtCharList
238 %*********************************************************
240 \subsection{Type @Int@}
242 %*********************************************************
245 instance Bounded Int where
249 instance Enum Int where
251 | x == maxBound = error "Prelude.Enum.succ{Int}: tried to take `succ' of maxBound"
252 | otherwise = x `plusInt` oneInt
254 | x == minBound = error "Prelude.Enum.pred{Int}: tried to take `pred' of minBound"
255 | otherwise = x `minusInt` oneInt
260 {-# INLINE enumFrom #-}
261 enumFrom (I# x) = build (\ c n -> eftIntFB c n x 2147483647#)
262 -- Blarg: technically I guess enumFrom isn't strict!
264 {-# INLINE enumFromTo #-}
265 enumFromTo (I# x) (I# y) = build (\ c n -> eftIntFB c n x y)
267 {-# INLINE enumFromThen #-}
268 enumFromThen (I# x1) (I# x2) = build (\ c n -> efdIntFB c n x1 x2)
270 {-# INLINE enumFromThenTo #-}
271 enumFromThenTo (I# x1) (I# x2) (I# y) = build (\ c n -> efdtIntFB c n x1 x2 y)
273 {-# INLINE eftIntFB #-}
274 eftIntFB c n x y | x ># y = n
277 go x = I# x `c` if x ==# y then n else go (x +# 1#)
278 -- Watch out for y=maxBound; hence ==, not >
279 -- Be very careful not to have more than one "c"
280 -- so that when eftInfFB is inlined we can inline
281 -- whatver is bound to "c"
283 eftIntList x y | x ># y = []
286 go x = I# x : if x ==# y then [] else go (x +# 1#)
289 -- For enumFromThenTo we give up on inlining; so we don't worry
290 -- about duplicating occurrences of "c"
291 efdtIntFB c n x1 x2 y
292 | delta >=# 0# = if x1 ># y then n else go_up x1
293 | otherwise = if x1 <# y then n else go_dn x1
296 go_up x | y -# x <# delta = I# x `c` n
297 | otherwise = I# x `c` go_up (x +# delta)
298 go_dn x | y -# x ># delta = I# x `c` n
299 | otherwise = I# x `c` go_dn (x +# delta)
302 | delta >=# 0# = if x1 ># y then [] else go_up x1
303 | otherwise = if x1 <# y then [] else go_dn x1
306 go_up x | y -# x <# delta = [I# x]
307 | otherwise = I# x : go_up (x +# delta)
308 go_dn x | y -# x ># delta = [I# x]
309 | otherwise = I# x : go_dn (x +# delta)
312 | delta >=# 0# = go_up x1
313 | otherwise = go_dn x1
316 go_up x | 2147483647# -# x <# delta = I# x `c` n
317 | otherwise = I# x `c` go_up (x +# delta)
318 go_dn x | (-2147483648#) -# x ># delta = I# x `c` n
319 | otherwise = I# x `c` go_dn (x +# delta)
322 | delta >=# 0# = go_up x1
323 | otherwise = go_dn x1
326 go_up x | 2147483647# -# x <# delta = [I# x]
327 | otherwise = I# x : go_up (x +# delta)
328 go_dn x | (-2147483648#) -# x ># delta = [I# x]
329 | otherwise = I# x : go_dn (x +# delta)
333 "eftIntList" eftIntFB (:) [] = eftIntList
334 "efdIntList" efdIntFB (:) [] = efdIntList
335 "efdtIntList" efdtIntFB (:) [] = efdtIntList