X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=GHC%2FEnum.lhs;h=ac6e9a916a7d7967111d8776249dbee505c0ed77;hb=HEAD;hp=8441c765bc7ac603c779642d800367639c3911ca;hpb=10de2c656f74562b662c22928be85e1b3ccda796;p=ghc-base.git diff --git a/GHC/Enum.lhs b/GHC/Enum.lhs index 8441c76..ac6e9a9 100644 --- a/GHC/Enum.lhs +++ b/GHC/Enum.lhs @@ -1,5 +1,5 @@ \begin{code} -{-# OPTIONS_GHC -XNoImplicitPrelude #-} +{-# LANGUAGE NoImplicitPrelude, BangPatterns, MagicHash #-} {-# OPTIONS_HADDOCK hide #-} ----------------------------------------------------------------------------- -- | @@ -350,62 +350,72 @@ instance Enum Char where -- We can do better than for Ints because we don't -- have hassles about arithmetic overflow at maxBound {-# INLINE [0] eftCharFB #-} -eftCharFB c n x y = go x +eftCharFB :: (Char -> a -> a) -> a -> Int# -> Int# -> a +eftCharFB c n x0 y = go x0 where go x | x ># y = n | otherwise = C# (chr# x) `c` go (x +# 1#) -eftChar x y | x ># y = [] - | otherwise = C# (chr# x) : eftChar (x +# 1#) y +eftChar :: Int# -> Int# -> String +eftChar x y | x ># y = [] + | otherwise = C# (chr# x) : eftChar (x +# 1#) y -- For enumFromThenTo we give up on inlining {-# NOINLINE [0] efdCharFB #-} +efdCharFB :: (Char -> a -> a) -> a -> Int# -> Int# -> a efdCharFB c n x1 x2 | delta >=# 0# = go_up_char_fb c n x1 delta 0x10FFFF# | otherwise = go_dn_char_fb c n x1 delta 0# where - delta = x2 -# x1 + !delta = x2 -# x1 +efdChar :: Int# -> Int# -> String efdChar x1 x2 | delta >=# 0# = go_up_char_list x1 delta 0x10FFFF# | otherwise = go_dn_char_list x1 delta 0# where - delta = x2 -# x1 + !delta = x2 -# x1 {-# NOINLINE [0] efdtCharFB #-} +efdtCharFB :: (Char -> a -> a) -> a -> Int# -> Int# -> Int# -> a efdtCharFB c n x1 x2 lim | delta >=# 0# = go_up_char_fb c n x1 delta lim | otherwise = go_dn_char_fb c n x1 delta lim where - delta = x2 -# x1 + !delta = x2 -# x1 +efdtChar :: Int# -> Int# -> Int# -> String efdtChar x1 x2 lim | delta >=# 0# = go_up_char_list x1 delta lim | otherwise = go_dn_char_list x1 delta lim where - delta = x2 -# x1 + !delta = x2 -# x1 -go_up_char_fb c n x delta lim - = go_up x +go_up_char_fb :: (Char -> a -> a) -> a -> Int# -> Int# -> Int# -> a +go_up_char_fb c n x0 delta lim + = go_up x0 where go_up x | x ># lim = n | otherwise = C# (chr# x) `c` go_up (x +# delta) -go_dn_char_fb c n x delta lim - = go_dn x +go_dn_char_fb :: (Char -> a -> a) -> a -> Int# -> Int# -> Int# -> a +go_dn_char_fb c n x0 delta lim + = go_dn x0 where go_dn x | x <# lim = n | otherwise = C# (chr# x) `c` go_dn (x +# delta) -go_up_char_list x delta lim - = go_up x +go_up_char_list :: Int# -> Int# -> Int# -> String +go_up_char_list x0 delta lim + = go_up x0 where go_up x | x ># lim = [] | otherwise = C# (chr# x) : go_up (x +# delta) -go_dn_char_list x delta lim - = go_dn x +go_dn_char_list :: Int# -> Int# -> Int# -> String +go_dn_char_list x0 delta lim + = go_dn x0 where go_dn x | x <# lim = [] | otherwise = C# (chr# x) : go_dn (x +# delta) @@ -443,7 +453,7 @@ instance Enum Int where {-# INLINE enumFrom #-} enumFrom (I# x) = eftInt x maxInt# - where I# maxInt# = maxInt + where !(I# maxInt#) = maxInt -- Blarg: technically I guess enumFrom isn't strict! {-# INLINE enumFromTo #-} @@ -468,15 +478,15 @@ instance Enum Int where eftInt :: Int# -> Int# -> [Int] -- [x1..x2] -eftInt x y | x ># y = [] - | otherwise = go x +eftInt x0 y | x0 ># y = [] + | otherwise = go x0 where go x = I# x : if x ==# y then [] else go (x +# 1#) {-# INLINE [0] eftIntFB #-} eftIntFB :: (Int -> r -> r) -> r -> Int# -> Int# -> r -eftIntFB c n x y | x ># y = n - | otherwise = go x +eftIntFB c n x0 y | x0 ># y = n + | otherwise = go x0 where go x = I# x `c` if x ==# y then n else go (x +# 1#) -- Watch out for y=maxBound; hence ==, not > @@ -518,8 +528,8 @@ efdtIntUp :: Int# -> Int# -> Int# -> [Int] efdtIntUp x1 x2 y -- Be careful about overflow! | y <# x2 = if y <# x1 then [] else [I# x1] | otherwise = -- Common case: x1 <= x2 <= y - let delta = x2 -# x1 -- >= 0 - y' = y -# delta -- x1 <= y' <= y; hence y' is representable + let !delta = x2 -# x1 -- >= 0 + !y' = y -# delta -- x1 <= y' <= y; hence y' is representable -- Invariant: x <= y -- Note that: z <= y' => z + delta won't overflow @@ -533,8 +543,8 @@ efdtIntUpFB :: (Int -> r -> r) -> r -> Int# -> Int# -> Int# -> r efdtIntUpFB c n x1 x2 y -- Be careful about overflow! | y <# x2 = if y <# x1 then n else I# x1 `c` n | otherwise = -- Common case: x1 <= x2 <= y - let delta = x2 -# x1 -- >= 0 - y' = y -# delta -- x1 <= y' <= y; hence y' is representable + let !delta = x2 -# x1 -- >= 0 + !y' = y -# delta -- x1 <= y' <= y; hence y' is representable -- Invariant: x <= y -- Note that: z <= y' => z + delta won't overflow @@ -548,8 +558,8 @@ efdtIntDn :: Int# -> Int# -> Int# -> [Int] efdtIntDn x1 x2 y -- Be careful about underflow! | y ># x2 = if y ># x1 then [] else [I# x1] | otherwise = -- Common case: x1 >= x2 >= y - let delta = x2 -# x1 -- <= 0 - y' = y -# delta -- y <= y' <= x1; hence y' is representable + let !delta = x2 -# x1 -- <= 0 + !y' = y -# delta -- y <= y' <= x1; hence y' is representable -- Invariant: x >= y -- Note that: z >= y' => z + delta won't underflow @@ -563,8 +573,8 @@ efdtIntDnFB :: (Int -> r -> r) -> r -> Int# -> Int# -> Int# -> r efdtIntDnFB c n x1 x2 y -- Be careful about underflow! | y ># x2 = if y ># x1 then n else I# x1 `c` n | otherwise = -- Common case: x1 >= x2 >= y - let delta = x2 -# x1 -- <= 0 - y' = y -# delta -- y <= y' <= x1; hence y' is representable + let !delta = x2 -# x1 -- <= 0 + !y' = y -# delta -- y <= y' <= x1; hence y' is representable -- Invariant: x >= y -- Note that: z >= y' => z + delta won't underflow