Попытка выяснить правильный тип для этого - PullRequest
1 голос
/ 15 апреля 2020

Извинения, это будет несколько нуб-i sh вопрос. У меня есть объект из библиотеки slick, который имеет такой тип:

Query[(Rep[String], Rep[String]), (String, String), Seq]

Я пытаюсь написать функцию, которая принимает запросы в качестве аргументов, хотя последовательности в них имеют неопределенную длину - ie, это также может быть:

Query[(Rep[String], Rep[String], Rep[String]), (String, String, String), Seq]

Таким образом, первые два компонента имеют три элемента, а не два. Я не могу понять, как это делается. Я пробовал различные ошибочные перестановки, такие как Query[Product[Rep[String]], Product[String], Seq], но безрезультатно, и даже то, что я предположил, было бы ядерным вариантом простого использования Any, не работает. Мои сообщения об ошибках похожи на

[error]  found   : Option[slick.driver.H2Driver.api.Query[(slick.driver.H2Driver.api.Rep[String], slick.driver.H2Driver.api.Rep[String]),(String, St
ring),Seq]]
[error]     (which expands to)  Option[slick.lifted.Query[(slick.lifted.Rep[String], slick.lifted.Rep[String]),(String, String),Seq]]
[error]  required: Option[slick.driver.H2Driver.api.Rep[scala.concurrent.Future[List[String]]]]
[error]     (which expands to)  Option[slick.lifted.Rep[scala.concurrent.Future[List[String]]]]
[error]       ReturnFunctions.completeQuery(db, query, serialize_and_send)

Я думаю, что моя неспособность решить эту проблему может отражать фундаментальное отсутствие понимания scala, строго типизированных языков в целом и, возможно, также вычислений в целом. Должен ли я разрешить этот запрос в какой-то более определенной форме, прежде чем пытаться передать его в функцию? Я также подозреваю, что неправильно интерпретирую исходный тип - что означают в этом контексте паратезы? Может быть, Query ожидает получить три набора параметров, один за другим, например, когда вы делаете fn (arg1) (arg2) (arg3) = ...?

Любая помощь с этой тревожной дилеммой с благодарностью получил.

Ответы [ 2 ]

1 голос
/ 15 апреля 2020

Рассмотрим форму Query конструктора типа

Query[+E, U, C[_]]

Мы говорим Query это конструктор типа , потому что он создает конкретный тип из заданные аргументы типа E, U и C[_], аналогично тому, как функция создает конкретное значение из заданных аргументов функции.

Теперь давайте попробуем деконструировать конкретный тип

Query[(Rep[String], Rep[String]), (String, String), Seq]

в составляющие его параметры типа. У нас есть

E     = (Rep[String], Rep[String])
U     = (String, String)
C[_]  = Seq

Примечание (A, B) - это просто синтактика c сахар для Tuple2[A, B], таким образом

E     = (Rep[String], Rep[String]) = Tuple2[Rep[String], Rep[String]]
U     = (String, String)           = Tuple2[String, String]
C[_]  = Seq                        = Seq

Возможно, вы задаетесь вопросом об этом подчеркивании в C[_]. Это указывает, что параметр типа C должен быть конструктором типа, а не конкретным типом. Например, Seq является конструктором типа, а Seq[Int] - нет. Кроме того, вы можете быть удивлены этим + в +E. Это определяет отношение наследования параметризованных типов или, другими словами, дисперсию, например, оно указывает, является ли Seq[Dog] подтипом Seq[Animal].

Наконец, позволяет записать результирующий конкретный тип во всей его полноте

Query[Tuple2[Rep[String], Rep[String]], Tuple2[String, String], Seq]
1 голос
/ 15 апреля 2020

Я также подозреваю, что неправильно интерпретирую исходный тип - что означают скобки в этом контексте?

Вы рассмотрели разумную расширенную область, но давайте попробуем помочь.

Тип Query всегда имеет три параметра типа. Вы увидите их написанными как Query[M, U, C].

Первый параметр, M, является кортежем. Вот что в этом контексте означают скобки.

В вашем первом примере M - это кортеж из двух элементов; а во втором это три. Такая же ситуация существует для второго параметра, U. В Essential Slick .

в Scala есть несколько общих параметров: c. Это означает, что вы можете сказать что-то вроде:

def foo[M, U, C[_]](q: Query[M,U,C]) = ???

Мы определили метод с:

  • параметрами трех типов; и
  • с аргументом запроса, который имеет эти типы.

Мы ничего не говорили о M, U или о C (кроме того, что это тип, который принимает тип в качестве аргумента). Это означает, что мы мало что можем с ними сделать, но вам может и не понадобиться.

Пост о обогащении запросов в Slick дает более длинный (связанный) пример, который может быть полезен .

Как предполагает Дмитрий, лучшим путем было бы создать конкретный пример того, чего вы хотели бы достичь, и работать оттуда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...