compare () () = EQ
instance Enum () where
- succ x = x
- pred x = x
+ succ x = error "Prelude.Enum.succ{()}: not possible"
+ pred x = error "Prelude.Enum.pred{()}: not possible"
toEnum 0 = ()
- toEnum _ = error "Prelude.Enum.().toEnum: argument not 0"
+ toEnum _ = error "Prelude.Enum.toEnum{()}: argument not 0"
fromEnum () = 0
enumFrom () = [()]
enumFromThen () () = [()]
%*********************************************************
\begin{code}
-data Ordering = LT | EQ | GT deriving (Eq, Ord, Enum, Bounded, Show {- Read -})
+data Ordering = LT | EQ | GT deriving (Eq, Ord, Enum, Bounded, Show {- in PrelRead: Read -})
\end{code}
instance Enum Char where
succ c@(C# c#)
| not (ord# c# ==# 255#) = C# (chr# (ord# c# +# 1#))
- | otherwise = error ("Prelude.Enum{Char}.succ: out of range " ++ show c)
+ | otherwise = error ("Prelude.Enum.succ{Char}: tried to take `succ' of maxBound")
pred c@(C# c#)
| not (ord# c# ==# 0#) = C# (chr# (ord# c# -# 1#))
- | otherwise = error ("Prelude.Enum{Char}.succ: out of range " ++ show c)
+ | otherwise = error ("Prelude.Enum.pred{Char}: tried to to take `pred' of minBound")
toEnum (I# i) | i >=# 0# && i <=# 255# = C# (chr# i)
- | otherwise = error ("Prelude.Enum.Char.toEnum:out of range: " ++ show (I# i))
- fromEnum (C# c) = I# (ord# c)
+ | otherwise = error ("Prelude.Enum.toEnum{Char}: out of range: " ++ show (I# i))
+ fromEnum (C# c) = I# (ord# c)
- enumFrom (C# c) = efttCh (ord# c) 1# (># 255#)
- enumFromTo (C# c1) (C# c2) = efttCh (ord# c1) 1# (># (ord# c2))
+ enumFrom (C# c) = efttCh (ord# c) 1# (># 255#)
+ enumFromTo (C# c1) (C# c2)
+ | c1 `leChar#` c2 = efttCh (ord# c1) 1# (># (ord# c2))
+ | otherwise = efttCh (ord# c1) (negateInt# 1#) (<# (ord# c2))
enumFromThen (C# c1) (C# c2)
| c1 `leChar#` c2 = efttCh (ord# c1) (ord# c2 -# ord# c1) (># 255#)
isLower c = c >= 'a' && c <= 'z' ||
c >= '\xDF' && c <= '\xF6' ||
c >= '\xF8' && c <= '\xFF'
+isAsciiLower c = c >= 'a' && c <= 'z'
+isAsciiUpper c = c >= 'A' && c <= 'Z'
+
isAlpha c = isLower c || isUpper c
isDigit c = c >= '0' && c <= '9'
isOctDigit c = c >= '0' && c <= '7'
-- Case-changing operations
toUpper, toLower :: Char -> Char
-toUpper c
+toUpper c@(C# c#)
+ | isAsciiLower c = C# (chr# (ord# c# -# 32#))
+ | isAscii c = c
+ -- fall-through to the slower stuff.
| isLower c && c /= '\xDF' && c /= '\xFF'
- = toEnum (fromEnum c - fromEnum 'a' + fromEnum 'A')
- | otherwise
- = c
+ = toEnum (fromEnum c - fromEnum 'a' + fromEnum 'A')
+ | otherwise
+ = c
+
-toLower c | isUpper c = toEnum (fromEnum c - fromEnum 'A'
+
+toLower c@(C# c#)
+ | isAsciiUpper c = C# (chr# (ord# c# +# 32#))
+ | isAscii c = c
+ | isUpper c = toEnum (fromEnum c - fromEnum 'A'
+ fromEnum 'a')
- | otherwise = c
+ | otherwise = c
asciiTab :: [String]
asciiTab = -- Using an array drags in the array module. listArray ('\NUL', ' ')
| x ==# y = EQ
| otherwise = GT
+instance Bounded Int where
+ minBound = -2147483648 -- GHC <= 2.09 had this at -2147483647
+ maxBound = 2147483647
+
instance Enum Int where
- succ x = x+1
- pred x = x-1
+ succ x
+ | x == maxBound = error "Prelude.Enum.succ{Int}: tried to take `succ' of maxBound"
+ | otherwise = x+1
+ pred x
+ | x == minBound = error "Prelude.Enum.pred{Int}: tried to take `pred' of minBound"
+ | otherwise = x-1
+
toEnum x = x
fromEnum x = x
#ifndef USE_FOLDR_BUILD
- enumFrom (I# c) = eftInt c 1#
- enumFromTo (I# c1) (I# c2) = efttInt c1 1# (># c2)
- enumFromThen (I# c1) (I# c2) = eftInt c1 (c2 -# c1)
+ enumFrom (I# c) = efttInt True c 1# (\ _ -> False)
+
+ enumFromTo (I# c1) (I# c2)
+ | c1 <# c2 = efttInt True c1 1# (># c2)
+ | otherwise = efttInt False c1 (negateInt# 1#) (<# c2)
+
+ enumFromThen (I# c1) (I# c2)
+ | c1 <# c2 = efttInt True c1 (c2 -# c1) (\ _ -> False)
+ | otherwise = efttInt False c1 (c2 -# c1) (\ _ -> False)
enumFromThenTo (I# c1) (I# c2) (I# c3)
- | c1 <=# c2 = efttInt c1 (c2 -# c1) (># c3)
- | otherwise = efttInt c1 (c2 -# c1) (<# c3)
+ | c1 <=# c2 = efttInt True c1 (c2 -# c1) (># c3)
+ | otherwise = efttInt False c1 (c2 -# c1) (<# c3)
#else
{-# INLINE enumFrom #-}
let g x = if x <= y then x `c` g (x `plusInt` 1) else n in g x)
#endif
-efttInt :: Int# -> Int# -> (Int# -> Bool) -> [Int]
-efttInt init step done
- = go init
- where
- go now | done now = []
- | otherwise = I# now : go (now +# step)
-
-eftInt :: Int# -> Int# -> [Int]
-eftInt init step
- = go init
+efttInt :: Bool -> Int# -> Int# -> (Int# -> Bool) -> [Int]
+efttInt increasing init step done = go init
where
- go now = I# now : go (now +# step)
-
+ go now
+ | done now = []
+ | increasing && now ># nxt = [I# now] -- overflowed
+ | not increasing && now <# nxt = [I# now] -- underflowed
+ | otherwise = I# now : go nxt
+ where
+ nxt = now +# step
instance Num Int where
(+) x y = plusInt x y
-- Following chks for zero divisor are non-standard (WDP)
a `quot` b = if b /= 0
then a `quotInt` b
- else error "Prelude.Integral{Int}.quot: divide by 0\n"
+ else error "Prelude.Integral.quot{Int}: divide by 0"
a `rem` b = if b /= 0
then a `remInt` b
- else error "Prelude.Integral{Int}.rem: divide by 0\n"
+ else error "Prelude.Integral.rem{Int}: divide by 0"
x `div` y = if x > 0 && y < 0 then quotInt (x-y-1) y
else if x < 0 && y > 0 then quotInt (x-y+1) y
-- you get slightly better code if you let the compiler
-- see them right here:
n `quot` d = if d /= 0 then q else
- error "Prelude.Integral{Integer}.quot: divide by 0\n"
+ error "Prelude.Integral.quot{Integer}: divide by 0"
where (q,_) = quotRem n d
n `rem` d = if d /= 0 then r else
- error "Prelude.Integral{Integer}.rem: divide by 0\n"
+ error "Prelude.Integral.rem{Integer}: divide by 0"
where (_,r) = quotRem n d
n `div` d = q where (q,_) = divMod n d
n `mod` d = r where (_,r) = divMod n d
toEnum n = toInteger n
fromEnum n = toInt n
enumFrom n = n : enumFrom (n + 1)
- enumFromThen m n = en' m (n - m)
+ enumFromThen e1 e2 = en' e1 (e2 - e1)
where en' a b = a : en' (a + b) b
- enumFromTo n m = takeWhile (<= m) (enumFrom n)
- enumFromThenTo n m p = takeWhile (if m >= n then (<= p) else (>= p))
- (enumFromThen n m)
+ enumFromTo n m
+ | n <= m = takeWhile (<= m) (enumFrom n)
+ | otherwise = takeWhile (>= m) (enumFromThen n (n-1))
+ enumFromThenTo n m p = takeWhile pred (enumFromThen n m)
+ where
+ pred | m >= n = (<= p)
+ | otherwise = (>= p)
instance Show Integer where
showsPrec x = showSignedInteger x
toEnum = fromIntegral
fromEnum = fromInteger . truncate -- may overflow
enumFrom = numericEnumFrom
+ enumFromTo = numericEnumFromTo
enumFromThen = numericEnumFromThen
enumFromThenTo = numericEnumFromThenTo
enumFromThen = numericEnumFromThen
enumFromThenTo = numericEnumFromThenTo
-numericEnumFrom :: (Real a) => a -> [a]
-numericEnumFromThen :: (Real a) => a -> a -> [a]
-numericEnumFromThenTo :: (Real a) => a -> a -> a -> [a]
+numericEnumFrom :: (Fractional a) => a -> [a]
numericEnumFrom = iterate (+1)
+
+numericEnumFromThen :: (Fractional a) => a -> a -> [a]
numericEnumFromThen n m = iterate (+(m-n)) n
-numericEnumFromThenTo n m p = takeWhile (if m >= n then (<= p) else (>= p))
- (numericEnumFromThen n m)
+
+numericEnumFromTo :: (Ord a, Fractional a) => a -> a -> [a]
+numericEnumFromTo n m = takeWhile (<= m + 1/2) (numericEnumFrom n)
+
+numericEnumFromThenTo :: (Ord a, Fractional a) => a -> a -> a -> [a]
+numericEnumFromThenTo e1 e2 e3 = takeWhile pred (numericEnumFromThen e1 e2)
+ where
+ mid = (e2 - e1) / 2
+ pred | e2 > e1 = (<= e3 + mid)
+ | otherwise = (>= e3 + mid)
+
\end{code}
@approxRational@, applied to two real fractional numbers x and epsilon,
instance (Integral a) => Enum (Ratio a) where
succ x = x + 1
pred x = x - 1
- enumFrom = iterate ((+)1)
- enumFromThen n m = iterate ((+)(m-n)) n
+
toEnum n = fromIntegral n :% 1
fromEnum = fromInteger . truncate
+ enumFrom = bounded_iterator True (1)
+ enumFromThen n m = bounded_iterator (diff >= 0) diff n
+ where diff = m - n
+
+
+bounded_iterator :: (Ord a, Num a) => Bool -> a -> a -> [a]
+bounded_iterator inc step v
+ | inc && v > new_v = [v] -- oflow
+ | not inc && v < new_v = [v] -- uflow
+ | otherwise = v : bounded_iterator inc step new_v
+ where
+ new_v = v + step
+
ratio_prec :: Int
ratio_prec = 7