Is it ok, to create case classes with floating point fields, like:
case class SomeClass(a:Double, b:Double)
I guess auto generated equal method won't work in this case. Is overriding equals the best solution?
EDIT:
if overriding equals is the way to go, I would like to avoid hardcoding epsilon ( where epsilon is defined like => |this.a-a|< epsilon). This won't compile:
case class SomeClass(a:Double, b:Double, implicit epsilon:Double)
I am looking for a way to pass epsilon without passing concert value each time (some "implicit" magic).
I have also follow up more general question, how would you define hashcode for class with only floating point fields?
Ah, the joy of floating point numbers.
I think it is not a good idea to override equals with a fuzzy comparison. It violates all sorts of things that you usually take for granted with equality. Imagine a, b and c are some case classes with a fuzzy equals. Then it is possible to have a, b, c such that a==b, b==c but a!=c.
Then there is the behavior of hashcode to consider. If you override equals with fuzzy equality and do not override hashcode, you will not be able to use the resulting object in a hashmap or set, because a==b but a.hashcode!=b.hashcode.
The best way to solve the problem is to define an operator like =~= that provides a fuzzy comparison in addition to equals/== which (at least for immutable objects in scala) means that objects are exactly identical so that you can replace one with the other without changing the result of a calculation.
If you also want the ability to configure the precision of the comparison via an implicit, that adds another level of complexity. Here is a more complete example:
Note that the implicit is not an argument of the class but of the operation.
You are correct. If you are worried about precision, then you will need to override equals: