Моя функция в Scala возвращает супертип, а мой класс типов не может с этим справиться - PullRequest
0 голосов
/ 18 октября 2019

Я пытаюсь выйти из строя, но когда я работаю над реальными проблемами, с которыми я борюсь, мне нужна помощь с некоторыми основами. Мне нравится идея класса типов и добавить больше неявных типов в будущем.

      trait Query {
       def queryDetails: QueryDetails
      }

      case class LocalQueryType(queryDetails: QueryDetails) extends Query
      case class JdbcQueryType(queryDetails: QueryDetails) extends Query

      def queryTypeFactory(queryDetails: QueryDetails): Query = {
         queryDetails.platform match {
            case c if queryDetails.platform.contains("-file://") => LocalQueryType(queryDetails)
            case _ => JdbcQueryType(queryDetails)
          }
      }

Затем у меня есть класс типов, который ищет локальные типы или типы Jdbc, но он не работает, поскольку он получает только тип запроса.

Я пытался использовать обобщенные типыкак:


     def queryTypeFactory[T<:Query](queryDetails: QueryDetails): T = {
         queryDetails.platform match {
            case c if queryDetails.platform.contains("-file://") => LocalQueryType(queryDetails)
            case _ => JdbcQueryType(queryDetails)
          }
     }

Добавление класса класса:


trait QueryTask[A] {
  def runQuery(a: A): String
}

object QueryTask {

    def apply[A](implicit sh: QueryTask[A]): QueryTask[A] = sh

    object ops {
      def runQuery[A: QueryTask](a: A) = QueryTask[A].runQuery(a)

      implicit class ShowOps[A: QueryTask](a: A) {
        def runQuery = QueryTask[A].runQuery(a)
      }
    }

    implicit val localQuery: QueryTask[LocalQueryType] =
      instance(localQueryType => s"running local: ${localQueryType.queryDetails.command} on platform: ${localQueryType.queryDetails.platform}")

    implicit val jdbcQuery: QueryTask[JdbcQueryType] =
      instance(jdbcQueryType => s"running jdbc: ${jdbcQueryType.queryDetails.command} on platform: ${jdbcQueryType.queryDetails.platform}")

  def instance[A](func: A => String): QueryTask[A] =
    new QueryTask[A] {
      def runQuery(a: A): String = func(a)
    }


Идея состоит в том, чтобы не использовать обычную фабрику или стратегию OO.

1 Ответ

0 голосов
/ 18 октября 2019

Подход класса класса, похоже, не работает в вашем случае использования.

Последствия разрешаются во время компиляции. Поэтому, чтобы решить, какой экземпляр вам нужен, QueryTask[LocalQueryType] или QueryTask[JdbcQueryType] компилятор должен знать, является ли тип A LocalQueryType или JdbcQueryType во время компиляции.

Но, похоже, вы решаете, что в зависимостиqueryDetails.platform.contains("-file://")

Кажется, вам нужно обычное сопоставление с образцом. Вы должны использовать шаблон класса типа, когда это необходимо.

...