Is comparing Floats with literal integers risky?


#1

One of the patterns that Elm 0.19 prevents, that formerly worked in 0.18 is illustrated by the following:

toJson : Maybe Float -> Json.Encode.Value
toJson maybeNumber =
    case maybeNumber of
        Just 1 ->
            Json.Encode.bool True

        Just n ->
                Json.Encode.float n

        Nothing ->
            Json.Encode.bool False

I can see preventing this is a good thing as pattern matching floats against literal integers can be risky because of rounding errors.

Yet, the following is accepted by the compiler:

toJson : Maybe Float -> Json.Encode.Value
toJson maybeNumber =
    case maybeNumber of
        Just n ->
            if n == 1 then
                Json.Encode.bool True

            else
                Json.Encode.float n

        Nothing ->
            Json.Encode.bool False

Is comparing with the == operator any less risky than pattern matching via case...of?


#2

Semi-related: https://github.com/eslint/eslint/issues/8447


#3

Since == is just an infix function, wouldn’t that imply that both sides are required to be of the same type in which case the compiler infers the literal value to be a float?

Now I’m also curious as to why it would matter either way since all numbers are ultimately double precision floats in JavaScript. Any integer that can be represented by a double precision float can be compared to literal integers (that again are limited to those which can be represented as doubles) without rounding issues. Or am I missing something?


#4

Elm doesn’t allow pattern-matching on floats. If you change the 1 literal to 1.0, you get the following error:

I cannot pattern match with floating point numbers:

12|         Just 1.0 ->
                    ^
Equality on floats can be unreliable, so you usually want to check that they are
nearby with some sort of (abs (actual - expected) < 0.001) check.

#5

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.