-efdtIntDn x1 x2 y -- x2 < x1
- | y ># x2 = if y ># x1 then [] else [I# x1]
- | otherwise
- = -- Common case: x1 > x2 >= y
- let
- delta = x2 -# x1
- y' = y -# delta
- -- NB: x1 <= y'; hence y' is representable
-
- -- Invariant: x >= y; and x+delta won't overflow
- go_dn x | x <# y' = [I# x]
- | otherwise = I# x : go_dn (x +# delta)
- in
- I# x1 : go_dn x2
+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
+
+ -- Invariant: x >= y
+ -- Note that: z >= y' => z + delta won't underflow
+ -- so we are guaranteed not to underflow if/when we recurse
+ go_dn x | x <# y' = [I# x]
+ | otherwise = I# x : go_dn (x +# delta)
+ in I# x1 : go_dn x2
+
+-- Requires x2 <= x1
+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
+
+ -- Invariant: x >= y
+ -- Note that: z >= y' => z + delta won't underflow
+ -- so we are guaranteed not to underflow if/when we recurse
+ go_dn x | x <# y' = I# x `c` n
+ | otherwise = I# x `c` go_dn (x +# delta)
+ in I# x1 `c` go_dn x2