There is a sum method in TraversableOnce that can only be used if the contained type is Numeric (otherwise it wonβt compile). I wonder if this can be used for another case (to avoid checking the runtime).
In particular, the case when we have two traits A and B. We want to have a method f that can be used only if the object inherits both A and B. But not if this applies only to one of them. I do not want to do another trait AB extends A with B I just want to be unable to use f if not both properties are inherited.
package com.example trait Base trait Foo extends Base { def g = println("foo bar " + toString) } trait Bar extends Base { def f = { if (!this.isInstanceOf[Foo]) error("this is not an instance of Foo") this.asInstanceOf[Foo].g } } object Test { def main(args: Array[String]): Unit = { object ab extends Foo with Bar object ba extends Bar with Foo object b extends Bar ab.f ba.f
EDIT: solution thanks to @Aaron Novstrup
trait Bar extends Base { self => def f(implicit ev: self.type <:< Foo) = { //self.asInstanceOf[Foo].g // [1] ev(this).g // [2] } }
Now in main , bf does not compile. Nice
EDIT 2: modified line [1] - [2] reflects changes in @Aaron Novstrup's answer
EDIT 3: without using self reflect changes in @Aaron Novstrup's answer
trait Bar extends Base { def f(implicit ev: this.type <:< Foo) = { ev(this).g } }
source share