Scala не переданный тип

У меня есть метод с такой подписью:

def fn1[A1, P, Q, E, U, C[_]](
  fn: A1 => Query[E, U, C],
  sorts: (E => Rep[_], String)*
)(implicit
  aShape: Shape[ColumnsShapeLevel, A1, P, A1],
  pShape: Shape[ColumnsShapeLevel, P, P, _]
) = ???

и в моем классе у меня есть интересный запрос, определенный как:

protected def base(id: Rep[Long]): Query[(entity1Table, entity2Table), (Entity1, Entity2), Seq] = ???

Теперь я хочу сделать что-то вроде этого:

fn1(base, (_._1.name, "name"))

или по крайней мере

fn1(base, (x => x._1.name, "name"))

но даже со вторым способом scala не может вывести тип x, то есть (entity1Table, entity2Table), поэтому для правильной компиляции я должен явно указать тип x, записывающий это

fn1(base, ((x: (entity1Table, entity2Table)) => x._1.name, "name"))

Почему scala не может определить тип и что я могу сделать, чтобы scala автоматически определяла тип?

попробуйте каррировать fn1, т.е. определите его как fn1(fn)(sorts), чтобы узнать, поможет ли это

francoisr 17.12.2018 11:45

спасибо, но, к сожалению, это не помогает

Gigitsu 17.12.2018 12:31
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
280
2

Ответы 2

Я думаю, это потому, что функции контравариантны: _._1.name может быть (entity1Table, entity2Table) => String или Any => String, и любой из них удовлетворяет ограничению типа, потому что последний является подклассом первого.

Это связано с тем, что параметры типа вашего sorts являются производными от параметра firstfn. Но если вы передадите их оба одновременно, компилятор еще ничего не знает о fn и, следовательно, не сможет получить sorts.

Вам необходимо настроить curry на ваш fn1, чтобы компилятор мог сначала работать с fn, а затем использовать производные типы, чтобы понять смысл sorts.

Меня немного смущает использование ваших терминов entity1Table и т. д., Поэтому я составил фиктивную схему для примера.

import slick.driver.H2Driver

import H2Driver.api._

case class Entity1(i: Int, s: String)
case class Entity2(i: Int, s: String)

class Entity1T(tag: Tag) extends Table[Entity1](tag, "Entity1s") {
  def id = column[Int]("id", O.PrimaryKey) // This is the primary key column
  def name = column[String]("name")

  def * = (id, name) <> (Entity1.tupled, Entity1.unapply)
}

val entity1Table = TableQuery[Entity1T]

class Entity2T(tag: Tag) extends Table[Entity2](tag, "Entity2s") {
  def id = column[Int]("id", O.PrimaryKey) // This is the primary key column
  def name = column[String]("name")

  def * = (id, name) <> (Entity2.tupled, Entity2.unapply)
}

val entity2Table = TableQuery[Entity2T]

Теперь я не уверен, какой из них ты хочешь, этот

def fn1[A1, P, Q, E, U, C[_]](
  fn: A1 => Query[E, U, C]
)(
  sort: (U => Rep[_], String)*
)(implicit
  aShape: Shape[ColumnsShapeLevel, A1, P, A1],
  pShape: Shape[ColumnsShapeLevel, P, P, _]
) = ???

protected def base1(id: Rep[Long]): Query[(TableQuery[Entity1T], TableQuery[Entity2T]), (Entity1T, Entity2T), Seq] = ???

val x1 = fn1(base1)((etq => etq._1.name, "name"))

Или этот,

def fn2[A1, P, Q, E, U, C[_]](
  fn: A1 => Query[E, U, C]
)(
  sort: (E => Rep[_], String)*
)(implicit
  aShape: Shape[ColumnsShapeLevel, A1, P, A1],
  pShape: Shape[ColumnsShapeLevel, P, P, _]
) = ???

protected def base2(id: Rep[Long]): Query[(Entity1T, Entity2T), (Entity1, Entity2), Seq] = ???

val x2 = fn1(base1)((etq => etq._1.name, "name"))

Насколько я могу судить, обе версии могут наследовать типы.

Вы имеете право ... Я использовал эти скобки {}, поэтому получаю ошибку компиляции, но в этом случае fn1(base1)((etq => etq._1.name, "name")) работает правильно. Извините за вводящий в заблуждение вопрос ... Что мне теперь делать? Лучше отметить свой ответ как правильный o Мне нужно удалить свой вопрос?

Gigitsu 17.12.2018 14:49

Другие вопросы по теме