scala – 在匹配/案例上依赖于路径的键入

sealed trait Desc {
  type T
}

trait Dataset[A] {
  def toDS[A] = new Dataset[A] {}
}
trait DataFrame {}


sealed trait DFDesc extends Desc {
  type T = Dummy
}

sealed trait DSDesc[A] extends Desc {
  type T = A
}

trait JobConstruction {
  def apply(desc: Desc): Job[desc.T]
}

sealed trait Job[DescType] {
  def description: Desc { type T = DescType }
}

abstract class DSJob[V] extends Job[V] {
  def result(con: JobConstruction): Dataset[V]
}

abstract class DFJob extends Job[Dummy] {
  def result(con: JobConstruction): DataFrame
}

trait Dummy {}

case class SampleDFDesc() extends DFDesc
case class SampleDFJob(description: SampleDFDesc) extends DFJob {
  override def result(con: JobConstruction) = new DataFrame {}
}
case class SampleDSDesc() extends DSDesc[Int]
case class SampleDSJob(description: SampleDSDesc) extends DSJob[Int] {
  override def result(con: JobConstruction) = new Dataset[Int] {}
}

object Main {
  val sampleConst = new JobConstruction {
    override def apply(desc: Desc): Job[desc.T] = desc match {
      case desc2: SampleDFDesc => SampleDFJob(desc2)
      case desc2: SampleDSDesc => SampleDSJob(desc2)
    }
  }
}

无法编译

/tmp/sample.scala:73: error: type mismatch;
found   : this.SampleDFJob
required: this.Job[desc.T]
      case desc2: SampleDFDesc => SampleDFJob(desc2)
                                            ^
/tmp/sample.scala:74: error: type mismatch;
found   : this.SampleDSJob
required: this.Job[desc.T]
      case desc2: SampleDSDesc => SampleDSJob(desc2)

编辑:

我想让它以某种方式工作:

case class SampleDepDesc(df: SampleDFDesc) extends DSDesc[Int]
case class SampleDepJob(description: SampleDepDesc) extends DSJob[Int] {
  override def result(con: JobConstruction): Dataset[Int] = con(description.df).result(con).toDS[Int]
}

最佳答案 它不是一个真正的解决方案,但您可以使用类型参数替换类型内部特征,此代码编译:

sealed trait Desc[T]

trait Dataset[A]
trait DataFrame

sealed trait DFDesc extends Desc[Dummy]

sealed trait DSDesc[A] extends Desc[A]

trait JobConstruction {
  def apply[A](desc: Desc[A]): Job[A]
}

sealed trait Job[A] {
  def description: Desc[A]
}

abstract class DSJob[V] extends Job[V] {
  def result: Dataset[V]
}

abstract class DFJob extends Job[Dummy] {
  def result: DataFrame
}

trait Dummy

case class SampleDFDesc() extends DFDesc
case class SampleDFJob(description: SampleDFDesc) extends DFJob {
  def result = new DataFrame {}
}
case class SampleDSDesc() extends DSDesc[Int]
case class SampleDSJob(description: SampleDSDesc) extends DSJob[Int] {
  def result = new Dataset[Int] {}
}

val sampleConst = new JobConstruction {
  override def apply[A](desc: Desc[A]): Job[A] = desc match {
    case desc2: SampleDFDesc => SampleDFJob(desc2)
    case desc2: SampleDSDesc => SampleDSJob(desc2)
  }
}

至于如何使路径依赖类型工作,我很好奇自己.

点赞