Python supports an elegant syntax for "chained comparisons", for example:
0 <= n < 256
meaning,
0 <= n and n < 256
Knowing that it's a fairly flexible language syntactically, is it possible to emulate this feature in Scala?
Daniel's answer is comprehensive, it's actually hard to add anything to it. As his answer presents one of the choices he mentioned, I'd like just to add my 2 cents and present a very short solution to the problem in the other way. The Daniel's description:
You could, theoretically, feed the result of the one of the methods to another method. I can think of two ways of doing that:
- Having <= return an object that has both the parameter it received and the result of the comparision, and having < use both these values as appropriate.
CmpChain
will serve as an accumulator of comparisions already made along with a free rightmost object, so that we can compare it to the next:
class CmpChain[T <% Ordered[T]](val left: Boolean, x: T) {
def <(y: T) = new CmpChain(left && x < y, y)
def <=(y: T) = new CmpChain(left && x <= y, y)
// > and >= are analogous
def asBoolean = left
}
implicit def ordToCmpChain[T <% Ordered[T]](x: T) = new AnyRef {
def cmp = new CmpChain(true, x)
}
implicit def rToBoolean[T](cc: CmpChain[T]): Boolean = cc.asBoolean
You can use it for any ordered types, like Int
s or Double
s:
scala> (1.cmp < 2 < 3 <= 3 < 5).asBoolean
res0: Boolean = true
scala> (1.0.cmp < 2).asBoolean
res1: Boolean = true
scala> (2.0.cmp < 2).asBoolean
res2: Boolean = false
Implicit conversion will produce Boolean
where it is supposed to be:
scala> val b: Boolean = 1.cmp < 2 < 3 < 3 <= 10
b: Boolean = false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With