Scala 类型类不适用于父类型

Scala typeclass not working for parent type

我有以下类型类:

trait Loader[A, B, C] {
  //Any Spark loader requires
  // A -> Input Type
  // B -> Output Type
  // C -> some type of implicit context provided by the compiler from 
  //      the sourounding environment.
  def load(input: A)(implicit context: C): B
}

object Loader {
  implicit object HiveLoader extends Loader[HiveTableSource, DataFrame, HiveContext] {
    def load(source: HiveTableSource)(implicit hc: HiveContext): DataFrame = {
      val db = source.db
      val tbl = source.tbl
      val df =  hc.sql(s"select * from $db.$tbl")
      df
    }
  }

  def loadDataSource[A,B,C](d: A)(implicit ldr: Loader[A,B,C], context: C):B = 
    ldr.load(d)
}

sealed trait DataSource
case class HiveTableSource(db: String, tbl: String) extends DataSource

当我尝试以下操作时,代码无法通过 "could not find implicit parameter ldr"

编译
c // this is of type DataSource

import Loader._ 

loadDataSource(c) //This Fails 

但是,如果我明确强制类型

LoadDataSource(c.asInstanceof[HiveTableSource]) The code compiles.

使用 asInstanceOf 是灾难的根源。见 "The Scalazzi Safe Scala Subset".

但是,如果您将 DataSource 视为 ADT(代数数据类型),那么您可以使用模式匹配来解决这个问题,但是您必须 select 类型类的实例你自己。

要做到这一点,必须有一组限制的可能数据源(很像 Option[A] 仅限于 Some[A]None)。我看到你已经封印了你的 DataSource 特质,所以你应该没问题。

sealed trait DataSource
final case class HiveTableSource(db: String, tbl: String) extends DataSource
final case class SomeOtherSource() extends DataSource

val c: DataSource = ???

c match {
  case s: HiveTableSource => loadDataSource(s)(HiveLoader)
  case s: SomeOtherSource => loadDataSource(s)(SomeOtherLoader)
}