简体   繁体   English

在Scala TypeClass中找不到隐式参数

[英]Could not Find Implicit parameter in scala typeclass

I am trying to create a type class based on the type data to load -- 我正在尝试基于要加载的类型数据创建类型类-

Here are the types: 类型如下:

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

here is the trait 这是特质

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

And here is the implementation: 这是实现:

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)

The compiler complains that it can not find implicit evidence for parameter, specificly in the "implicitly[ABC]: 编译器抱怨它找不到参数的隐式证据,特别是在“隐式[ABC]”中:

The goal is to have a typeclass that has different behavior for each type, and also use a different context (implicitly provided by the environment) 目标是拥有一个对每个类型具有不同行为的类型类,并且还使用不同的上下文(由环境隐式提供)

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

I did not try compiling it myself but I'm fairly sure that would work. 我没有尝试自己编译它,但是我很确定那是可行的。

loadDataSource[A: Loader, B, C](d: A) is desugared to loadDataSource[A, B, C](d: A)(implicit ev: Loader[A]) , which doesn't work here because Loader takes 3 type parameters. loadDataSource[A: Loader, B, C](d: A)替代为loadDataSource[A, B, C](d: A)(implicit ev: Loader[A]) ,在这里不起作用,因为Loader需要3种参数。 So you have to explicitly annotate the implicit parameter instead of using a context bound. 因此,您必须显式注释隐式参数,而不是使用上下文绑定。

In order to call Loader's load method, an implicit C must be provided. 为了调用Loader的load方法,必须提供一个隐式C。 That's why I added the additional context: C implicit parameter. 这就是为什么我添加了附加context: C隐式参数的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM