Way back when I started with haskell I noticed this, and switched to using this:
-- | Enumerate an inclusive range. Uses multiplication instead of successive -- addition to avoid loss of precision. -- -- Also it doesn't require an Enum instance. range :: (Num a, Ord a) => a -> a -> a -> [a] range start end step = go 0 where go i | step >= 0 && val > end = [] | step < 0 && val < end = [] | otherwise = val : go (i+1) where val = start + (i*step) It's always seemed better in every way, except syntax convenience. Wouldn't any approach with successive addition lose precision? On Tue, Aug 9, 2016 at 8:22 PM, Andrew Farmer <xicheko...@gmail.com> wrote: > Noticed this today: > > ghci> let xs = [0.0,0.1 .. 86400.0] in maximum xs > 86400.0000005062 > > enumFromThenTo is implemented by numericEnumFromThenTo: > > https://github.com/ghc/ghc/blob/a90085bd45239fffd65c01c24752a9 > bbcef346f1/libraries/base/GHC/Real.hs#L227 > > Which probably accumulates error in numericEnumFromThen with the (m+m-n): > > numericEnumFromThen n m = n `seq` m `seq` (n : numericEnumFromThen m > (m+m-n)) > > Why not define numericEnumFromThen as: > > numericEnumFromThen n m = let d = m - n in d `seq` go d n > where go delta x = x `seq` (x : go delta (x + delta)) > > (or with BangPatterns) > > numericEnumFromThen n m = go (m - n) n > where go !delta !x = x : go delta (x + delta) > > Seems like we'd save a lot of subtractions by using the worker function. > _______________________________________________ > ghc-devs mailing list > ghc-devs@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs >
_______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs