2015-11-05 178 views
0

我试图创建一个基于类型的数据加载类型的类 -无法找到斯卡拉类型类的隐含参数

以下是类型:

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) 

编译器抱怨说它无法找到隐含的参数证据,具体在“隐式地[ABC]”中:

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

回答

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) is desugared to loadDataSource[A, B, C](d: A)(implicit ev: Loader[A]),由于Loader需要3个类型参数,因此在此不起作用。所以你必须显式地注解隐式参数,而不是使用上下文绑定。

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

+0

进口Loader._ loadDataSource(c.src) 结果“找不到paramater LDR内含价值的任何想法 – user2726995

+0

你必须键入注释loadDataSource 所以'进口Loader._。?; loadDataSource [HiveTableSource,DataFrame,HiveContext](c.src)'我会相信。 –