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)
}
我有以下类型类:
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)
}