динамический полиморфизм скалы с инжектором и реализацией - PullRequest
0 голосов
/ 11 декабря 2018

Я узнал, что иерархия универсальных типов scala с другим именем атрибута динамический полиморфизм с экстракторами может решить части моей проблемы.Однако я также узнал, что кошки, котята и бесформенные могут стать путем к чистому решению.К сожалению, я пока не знаком ни с одним из них.Пытаясь построить из приведенного выше примера, я понял, что экстракторов недостаточно.

Как я могу создавать инжекторы?Может даже с бесформенным?И динамически создавать экземпляры подходящих объектов.

Ниже приведен более полный пример использования экстракторов, в котором описаны мои ошибки компиляции:

import org.apache.spark.sql.{Dataset, SparkSession}

sealed trait Db {
  def db: String

  def table: String
}

case class DataSource(override val db: String,
                      override val table: String)
  extends Db


trait Feed extends BaseConfiguration

trait FooFeedConfiguration extends Feed {
  def fooFeed: DataSource
}

trait FeedDataSourceExtractor[F <: Feed] {
  def extract(feedDs: F): DataSource
}

implicit val cellFeedEx = new FeedDataSourceExtractor[FooFeedConfiguration] {
  override def extract(feedDS: FooFeedConfiguration) = feedDS.fooFeed
}

trait BaseConfiguration {
  def applicationName: String
}

trait SparkDatasetProvider[T <: Product, C <: BaseConfiguration] {

  def provide(spark: SparkSession, c: C): Dataset[T]
}

def myFunction[T <: Product, F <: Feed, feedProvider <: SparkDatasetProvider[T, F]](spark: SparkSession, c: F)(implicit feedEx: FeedDataSourceExtractor[F]): Dataset[T] = {
  val dataSourceWithInterval = feedEx.extract(c)
  //FooFeedProvider.provideAndFilter(
  feedProvider.provide( // TODO why does this not compile.
    spark,
    //new FooFeedConfiguration  {
    new F {
      override val applicationName = c.applicationName
      override val feed // TODO need some kind of injector
      DataSource(dataSourceWithInterval.db, // real code performs some fancy logic here (on other attribute values)
        dataSourceWithInterval.table)
    }
  )
}

final case class FooFeed(foo: Int, bar: String)

object FeedProvider extends SparkDatasetProvider[FooFeed, FooFeedConfiguration] {
  override def provide(spark: SparkSession, c: FooFeedConfiguration) = {
    import spark.implicits._
    spark.sql(s"select * from ${c.fooFeed.db}.${c.fooFeed.table}").as[FooFeed]
  }
}

myFunction[FooFeed, FooFeedConfiguration, FeedProvider[FooFeed, FooFeedConfiguration]]()
// cant call FeedProvider
// all these type parameters (duplicated) seem to be not elegant. Is there a better way?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...