【问题标题】:Could not Find Implicit parameter in scala typeclass在 scala 类型类中找不到隐式参数
【发布时间】:2015-11-05 22:29:21
【问题描述】:

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

以下是类型:

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)

编译器抱怨它找不到参数的隐含证据,特别是在“implicitly[A.B.C]:

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

【问题讨论】:

    标签: scala apache-spark


    【解决方案1】:
    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 隐式参数。

    【讨论】:

    • import Loader._ loadDataSource(c.src) 导致“找不到参数 ldr 的隐含值。有什么想法吗?
    • 你必须输入 annotate loadDataSource 所以我相信import Loader._; loadDataSource[HiveTableSource, DataFrame, HiveContext](c.src) 会起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-29
    • 2018-03-16
    • 1970-01-01
    • 2018-01-13
    • 1970-01-01
    相关资源
    最近更新 更多