Scala:如何在特征中添加依赖于类型的方法?

标签 scala scala-2.10 traits

我有以下想法:

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's bad

ConstantBool(true) && ConstantInt(1) // (7)
ConstantInt(1) && ConstantBool(true) // (8) compiles but it's bad

如果 (1) 和 (2) 没有在正确的方案中应用,我希望 (1) 和 (2) 引发编译器异常。例如,虽然 (6) 和 (8) 当前可以编译,但它们不应该。 (5) 和 (7) 已经不编译了。
如何指定要应用这些方法的类型条件?

最佳答案

您可以使用通用类型约束(请参阅 this answer )来实现您想要的:

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

关于Scala:如何在特征中添加依赖于类型的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16769079/

相关文章:

scala - akka 将任务拆分为更小的结果并折叠结果

scala - 如何从TypeTag或同时获取ClassTag的ClassTag?

scala - 为什么 Scala 的 == 在 Int 的情况下不同?

scala - 如何模式匹配扩展多个特征的对象?

oop - 是否可以从特征中访问结构字段?

rust - 在为引用和非引用类型实现特性时,我是否必须实现特性两次?

scala - 在 REPL 中查找类型?

Scala 无形状函数对应于常规列表上的普通 "zipped"吗?

java - scala反射错误java

Scala 案例类复制方法在 2.9 和 2.10 之间的差异