Scala: how to add type dependent methods in a tag?

I have the following idea:

trait Generator[A] { def generate: Stream[A] // (1) If A <: Int def +(other: Generator[Int]): Generator[Int] = ( CustomGeneratorInt( (this.asInstanceOf[Generator[Int]].generate, other.generate) .zipped .map(_ + _)) ) // (2) If A <: Boolean def &&(other: Generator[Boolean]): Generator[Boolean] = ... } case class CustomGeneratorInt(val generate: Stream[Int]) extends Generator[Int] case class ConstantInt(i: Int) extends Generator[Int] { def generate = Stream(i) } case class ConstantBool(i: Boolean) extends Generator[Boolean] { def generate = Stream(i) } case class GeneratorRandomInt(i: Int) extends Generator[Int] { def generate = ... } ConstantInt(1) + ConstantInt(2) // (3) ok ConstantBool(true) && ConstantBool(false) // (4) ok ConstantInt(1) + ConstantBool(false) // (5) ConstantBool(true) + ConstantInt(1) // (6) compiles but it bad ConstantBool(true) && ConstantInt(1) // (7) ConstantInt(1) && ConstantBool(true) // (8) compiles but it bad 

I would like (1) and (2) to raise a compiler exception if they are not applied in the correct scheme. For example, although (6) and (8) are currently compiled, they should not. (5) and (7) are no longer compiled. How to specify this type condition for applying these methods?

+4
source share
1 answer

You can use generic type constraints (see this answer ) to achieve what you want:

 trait Generator[A] { def generate: Stream[A] def +(other: Generator[A])(implicit evidence: A =:= Int): Generator[Int] = ??? def &&(other: Generator[A])(implicit evidence: A =:= Boolean): Generator[Boolean] = ??? } case class GeneratorInt(i: Int) extends Generator[Int] { def generate = Stream(i) } case class GeneratorBool(i: Boolean) extends Generator[Boolean] { def generate = Stream(i) } GeneratorInt(1) + GeneratorInt(2) // (3) ok GeneratorBool(true) && GeneratorBool(false) // (4) ok GeneratorInt(1) + GeneratorBool(false) // (5) type mismatch GeneratorBool(true) + GeneratorInt(1) // (6) type mismatch GeneratorBool(true) && GeneratorInt(1) // (7) type mismatch GeneratorInt(1) && GeneratorBool(true) // (8) type mismatch 
+11
source

Source: https://habr.com/ru/post/1482917/


All Articles