From e3564f8971dde7cb0dac8a1f21732b21d46a2474 Mon Sep 17 00:00:00 2001 From: simonpj Date: Fri, 28 May 1999 19:19:20 +0000 Subject: [PATCH] [project @ 1999-05-28 19:19:20 by simonpj] Make the Enum Integer instance deforestable --- ghc/lib/std/PrelNum.lhs | 59 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/ghc/lib/std/PrelNum.lhs b/ghc/lib/std/PrelNum.lhs index 97c853c..b6fc0d1 100644 --- a/ghc/lib/std/PrelNum.lhs +++ b/ghc/lib/std/PrelNum.lhs @@ -348,21 +348,60 @@ instance Integral Integer where if signum r == negate (signum d) then (q - 1, r+d) else qr } -- Case-ified by WDP 94/10 +------------------------------------------------------------------------ instance Enum Integer where succ x = x + 1 pred x = x - 1 toEnum n = toInteger n fromEnum n = toInt n - enumFrom n = n : enumFrom (n + 1) - enumFromThen e1 e2 = en' e1 (e2 - e1) - where en' a b = a : en' (a + b) b - enumFromTo n m - | n <= m = takeWhile (<= m) (enumFrom n) - | otherwise = [] - enumFromThenTo n m p = takeWhile pred (enumFromThen n m) - where - pred | m >= n = (<= p) - | otherwise = (>= p) + + {-# INLINE enumFrom #-} + {-# INLINE enumFromThen #-} + {-# INLINE enumFromTo #-} + {-# INLINE enumFromThenTo #-} + enumFrom x = build (\c n -> enumDeltaIntegerFB c x 1) + enumFromThen x y = build (\c n -> enumDeltaIntegerFB c x (y-x)) + enumFromTo x lim = build (\c n -> enumDeltaToIntegerFB c n x 1 lim) + enumFromThenTo x y lim = build (\c n -> enumDeltaToIntegerFB c n x (y-x) lim) + +enumDeltaIntegerFB :: (Integer -> b -> b) -> Integer -> Integer -> b +enumDeltaIntegerFB c x d = x `c` enumDeltaIntegerFB c (x+d) d + +enumDeltaIntegerList :: Integer -> Integer -> [Integer] +enumDeltaIntegerList x d = x : enumDeltaIntegerList (x+d) d + +enumDeltaToIntegerFB c n x delta lim + | delta >= 0 = up_fb c n x delta lim + | otherwise = dn_fb c n x delta lim + +enumDeltaToIntegerList x delta lim + | delta >= 0 = up_list x delta lim + | otherwise = dn_list x delta lim + +up_fb c n x delta lim = go (x::Integer) + where + go x | x > lim = n + | otherwise = x `c` go (x+delta) +dn_fb c n x delta lim = go (x::Integer) + where + go x | x < lim = n + | otherwise = x `c` go (x+delta) + +up_list x delta lim = go (x::Integer) + where + go x | x > lim = [] + | otherwise = x : go (x+delta) +dn_list x delta lim = go (x::Integer) + where + go x | x < lim = [] + | otherwise = x : go (x+delta) + +{-# RULES +"enumDeltaInteger" enumDeltaIntegerFB (:) = enumDeltaIntegerList +"enumDeltaToInteger" enumDeltaToIntegerFB (:) [] = enumDeltaToIntegerList + #-} + +------------------------------------------------------------------------ instance Show Integer where showsPrec x = showSignedInteger x -- 1.7.10.4