Reputation: 15702
Let's say I define some operators for my class like this:
class A {
def +(f: Float) = /* ... */
}
val a: A = new A
This allows me to do a + 1f
, easy enough. What if I want to enable the lib's user to be able to write 1f + a
, too? How can I implement that?
Upvotes: 3
Views: 529
Reputation: 43330
In Scala 2.9 you can import this implicit conversion:
implicit def floatPlusAExtender (x: Float) =
new {
def + (a: A) = a + x
}
and use it as you wanted. Since Scala 2.10 you better do this conversion like so:
implicit class FloatPlusAExtender (x: Float) {
def + (a: A) = a + x
}
or even better like so:
implicit class FloatPlusAExtender (val x: Float) extends AnyVal {
def + (a: A) = a + x
}
The last way is called Value Class and in difference to preceding two it provides this functionality with zero overhead. (Thanks, axel22) This is also the new stuff that comes with 2.10
Or you can just modify A
like so:
class A {
def + (x: Float) = /* ... */
def +: (x: Float) = this + x
}
and use it like so:
1f +: a
The last approach is preferable.
Upvotes: 11
Reputation: 12852
One approach is the pimp-my-library-pattern:
class FloatWithPlusA(f: Float) {
def +(a: A) = a + f
}
implicit def floatPlusA(f: Float): FloatWithPlusA =
new FloatWithPlusA(f)
val a: A = new A
a + 1.0f /* a.+(1.0f) */
1.0f + a /* floatPlusA(1.0f).+(a) */
Another approach is adding a right-associative method, but with the obvious disadvantage that the syntax of the two operators varies:
class A {
val f: Float = 1.0f
def +(f: Float) = this.f + f
def +:(f: Float) = this.f + f
}
val a: A = new A
a + 1.0f
1.0f +: a
Upvotes: 3