[Haskell-cafe] Error with Float

Josh Hoyt joshhoyt at gmail.com
Tue Jul 19 19:42:59 EDT 2005

On 7/19/05, Cale Gibbard <cgibbard at gmail.com> wrote:
> The code you wrote below has a serious style problem that I thought
> I'd point out: you shouldn't use the IO monad for pure functions. You
> can define f as follows:
> [snip]

I agree on the stylistic front. Another approach is to make the
generator function return the list of values.

gen :: Double -> [Double]
gen x = (takeWhile (/= 0.0) $ iterate f x) ++ [0.0]
    where f x = let t = 2 * x in if t < 1 then t else t-1

showSteps :: [Double] -> [String]
showSteps xs = map showStep $ zip [1..] xs
    where showStep (n, x) = (show n) ++ ". Value is: " ++ (show x)

iogen :: Double -> IO ()
iogen x = mapM_ putStrLn $ showSteps $ gen x

I added the ++ [0.0] to gen so that it will generate the same list as
the original version.

To illustrate the generality of the floating-point inexactness
problem, I added the step numbering to compare with another
programming language. In Python:

def gen(x, n=1):
    t = x * 2.
    if t < 1.:
        c = t
        c = t - 1
    print '%d. Value is: %.16f' % (n, c)
    if c != 0:
        gen(c, n + 1)

Both programs terminate in the same number of steps, since their
floating-point types have the same underlying implementation. Python
has no Rational type to fall back on, however.

Josh Hoyt

More information about the Haskell-Cafe mailing list