I am trying to emulate != with <> in Scala.
implicit def conditional[A](left : A) = new {
| def<>[A](right : A) = (left != right)
| }
What are the case in which this emulation won't work
I am trying to emulate != with <> in Scala.
implicit def conditional[A](left : A) = new {
| def<>[A](right : A) = (left != right)
| }
What are the case in which this emulation won't work
This ought to always work, but perhaps not in the way you're envisioning. Do you expect the two types to be the same? If so, it should be
class Conditionalize[A](left: A) { def <>(right: A) = left != right }
implicit def conditional[A](left: A) = new Conditionalize(left)
if not, it's clearer to use a separate type parameter:
implicit def notequality[A](a: A) = new { def <>[B](b: B) = a != b }
The former will only work if the LHS does not need to be implicitly converted to be of the same type as the RHS. With conditional but not notequality defined:
implicit def int_to_string(i: Int) = i.toString
scala> "5" <> 5
res0: Boolean = false
scala> 5 <> "5"
<console>:9: error: type mismatch;
found : java.lang.String("5")
required: Int
5 <> "5"
because you can't chain implicits.
The latter case will will work just like !=. (Edit: with one special case regarding the null
value, due to its type Null
.)
Both of these will wrap primitives, which will make it slower for heavy-duty work. But Scala avoids the weirdnesses of Java where 0.0 == -0.0
but (new java.lang.Double(0.0)).equals(new java.lang.Double(-0.0))
is false, so you shouldn't notice the difference in outcome.
And if you wanted to, you could add @specialized
to make the comparators avoid boxing primitives at the cost of additional code size.
One thing to take notice of is that <>
has a different precedence than ==
, so some thing will not work without parenthesis. For example:
a <> b >> 2 // (a <> b) >> 2
a != b >> 2 // a != (b >> 2)