I'm writing a code generator which produces Scala output.
I need to emulate a ternary operator in such a way that the tokens leading up to '?' remain intact.
e.g. convert the expression c ? p : q
to c something
. The simple if(c) p else q
fails my criteria, as it requires putting if(
before c
.
My first attempt (still using c/p/q as above) is
c match { case(true) => p; case _ => q }
another option I found was:
class ternary(val g: Boolean => Any) { def |: (b:Boolean) = g(b) } implicit def autoTernary (g: Boolean => Any): ternary = new ternary(g)
which allows me to write:
c |: { b: Boolean => if(b) p else q }
I like the overall look of the second option, but is there a way to make it less verbose?
Thanks
Ternary operator which adds my improvement to the best of Rex Kerr’s and Michel Krämer’s implementations:
.
sealed trait TernaryResult[T] extends Any {
def |(op3: => T): T
}
class Ternary2ndOperand[T](val op2: T) extends AnyVal with TernaryResult[T] {
def |(op3: => T) = op2
}
class Ternary3rdOperand[T](val op2: T) extends AnyVal with TernaryResult[T] {
def |(op3: => T) = op3
}
class Ternary(val op1:Boolean) extends AnyVal {
def ?[A](op2: => A): TernaryResult[A] = if (op1) new Ternary2ndOperand(op2) else new Ternary3rdOperand(op2)
}
object Ternary {
implicit def toTernary(condition: Boolean) = new Ternary(condition)
}
Note the improvement over if else
is not just the 6 characters saved. With Scala IDE’s syntax coloring on keywords being the same (e.g. purple) for if
, else
, null
, and true
, there is better contrast in some cases (which isn't shown by the syntax coloring below as currently rendered on this site):
if (cond) true else null
cond ? true | null
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