无法在scala类型类中找到隐式参数

时间:2015-11-05 22:29:22

标签: scala apache-spark

我正在尝试根据要加载的类型数据创建一个类型类 -

以下是类型:

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

这是特质

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 environemnt..
  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: Loader, B, C](d: A) = implicitly[Loader[A,B,C]].load(d)

编译器抱怨它无法找到参数的隐式证据,具体在“隐式[A.B.C]:

目标是让每个类型具有不同行为的类型类,并使用不同的上下文(由环境隐式提供)

1 个答案:

答案 0 :(得分:4)

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

我没有尝试自己编译,但我相当确定会有效。

loadDataSource[A: Loader, B, C](d: A)被置于loadDataSource[A, B, C](d: A)(implicit ev: Loader[A]),这在这里不起作用,因为Loader需要3个类型参数。因此,您必须显式注释隐式参数,而不是使用上下文绑定。

为了调用Loader的load方法,必须提供隐式C.这就是为什么我添加了额外的context: C隐式参数。