Haskell floor function returns different results
haskell
Solution
in this case it returns the number greater than the argument which contradicts its definition.
It returns a number equal to its argument. As you said, it's about double precision. The numbers 3.9999999999999999 and 4 are simply equal to each other under 64-bit floating point rules.
but then it shouldn't compile given the importance of Haskell type safety
The problem is that Fractional literals like that have the polymorphic type `Fractional a => a`. That is they don't have to be doubles. For example, you could write `floor (3.9999999999999999 :: Rational)`, which will correctly return 3 because 3.9999999999999999 can be represented as a `Rational` without any loss in precision.
If Haskell made it an error to write `3.9999999999999999`, then you also wouldn't be able to write `3.9999999999999999 :: Rational`, which would be bad. So since a `Fractional` literal can be represented using many different types, some of which have infinite precision, it would be a big mistake for Haskell to restrict the number of legal `Fractional` literals based on `Double`'s limitations.
One might argue that Haskell should restrict `3.9999999999999999` when used as a `Double`, but not when used a `Rational`. However this would require instances of the `Fractional` type class to declare information about their precision (so that Haskell can use that information to decide whether a given literal is valid for that type), which it currently does not and which would be difficult (or impossible) to implement in a general, efficient and user-friendly manner (taking into account that the term "precision" can mean quite different things depending on whether we're talking about floating point numbers or fixed point numbers and whether they use base 2 or 10 (or anything else) to represent the numbers - either of which would be possible for instances of the `Fractional` type class).
Problem
I have a problem concerning Haskell `floor` function - it's supposed to return "the greatest integer not greater than the argument" but the expression `floor 3.9999999999999999` returns 4 rather than 3. It may have something to do with `Double` type precision but then it shouldn't compile given the importance of Haskell type safety, anyway in this case it returns the number greater than the argument which contradicts its definition.