This is why I like programming languages with type systems and "numerical towers":
Prelude> "9223372036854775807" == "9223372036854775808"
False
Prelude> "9223372036854775807" == 9223372036854775808
<interactive>:1:25:
No instance for (Num [Char])
arising from the literal `9223372036854775808'
at <interactive>:1:25-43
Possible fix: add an instance declaration for (Num [Char])
In the second argument of `(==)', namely `9223372036854775808'
In the expression: "9223372036854775807" == 9223372036854775808
In the definition of `it':
it = "9223372036854775807" == 9223372036854775808
Prelude>
Yes, it's the implicit conversion that matters. If you try to write 2 == 2.0 in Haskell, it will blow up, because doubles and integers are not the same type. You need to explicitly convert one of them to another representation before you can compare them. That guarantees defined and repeatable semantics at compile time, which I think is excellent.
(This is not strictly required, of course; you can write a typeclass that defines a two-paramater ==, instead of a -> a -> Bool, it could be a -> b -> Bool. But that's dumb, so nobody does.)