Как определить параметр функции по умолчанию, связанный с общим параметром?

Я пытаюсь реорганизовать функцию (qaru.site/info/42120/...), чтобы сделать ее несколько более общей. Здесь исходное определение функции:

def tryProcessSource(
  file: File,
  parseLine: (Int, String) => Option[List[String]] =
    (index, unparsedLine) => Some(List(unparsedLine)),
  filterLine: (Int, List[String]) => Option[Boolean] =
    (index, parsedValues) => Some(true),
  retainValues: (Int, List[String]) => Option[List[String]] =
    (index, parsedValues) => Some(parsedValues)
): Try[List[List[String]]] = {
  ???
}

И вот что я пытаюсь изменить:

def tryProcessSource[A <: Any](
  file: File,
  parseLine: (Int, String) => Option[List[String]] =
    (index, unparsedLine) => Some(List(unparsedLine)),
  filterLine: (Int, List[String]) => Option[Boolean] =
    (index, parsedValues) => Some(true),
  transformLine: (Int, List[String]) => Option[A] =
    (index, parsedValues) => Some(parsedValues)
): Try[List[A]] = {
  ???
}

Я продолжаю получать ошибку выделения в редакторе IntelliJ на Some(parsedValues), который гласит: "Выражение типа Some [List [String]] не соответствует ожидаемому типу Option [A]". Я не смог понять, как правильно изменить определение функции для удовлетворения требуемого условия; то есть ошибка исчезает.

Если я изменю transformLine на это (замените общий параметр A на Any)...

transformLine: (Int, List[String]) => Option[Any] =
  (index, parsedValues) => Some(parsedValues)

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

Любая помощь в этом очень ценится.

Ответ 1

В transformLine: (Int, List[String]) => Option[A] = (index, parsedValues) => whatever, parsedValues, очевидно, имеет тип List[String], поэтому Some(parsedValues) - Some[List[String]]. Для transformLine просто нет разумного значения по умолчанию.

Вы можете изменить его тип на (Int, A) => Option[A] или (Int, List[A]) => Option[List[A]] в зависимости от того, что вам нужно, и изменить предыдущие аргументы, но вы застряли в том, что строки String s, Мне нужно преобразовать их в A где-нибудь.

Ответ 2

После прочтения и повторного чтения Алексея Ромонова и ответа Ли, он дал мне понять, как реорганизовать это, чтобы заставить его работать. Кроме того, я думаю, что это может также подразумевать руководство относительно предоставления значений по умолчанию для функции.

Если я правильно понимаю, я пытаюсь объединить конкретный, в данном примере случай List[String] в параметре преобразования по умолчанию, с общим типом, в данном случае Option[A]. По сути, это перекрывает границу, на которой генерируется обобщенная копия функции компилятором для конкретного типа, предоставленного пользователем, и явно предоставленного List[String]. Это приводит меня к следующему руководству относительно определения общих функций:

При преобразовании конкретной функции, чтобы сделать ее общей, каждый параметр со значением по умолчанию, который напрямую взаимодействует с любым из общих параметров, вероятно, должен удаляться и помещаться в замкнутую конкретную функцию, которая переадресует вызов общей функции.


Итак, с учетом этого руководства, разрешите переработку исходного кода...

Конкретная функция выглядит так (очень похожая на исходную версию с предварительным генератором, которая также включала желаемые конкретные параметры по умолчанию):

def tryProcessSource(
  file: File,
  parseLine: (Int, String) => Option[List[String]] =
    (index, unparsedLine) => Some(List(unparsedLine)),
  filter: (Int, List[String]) => Option[Boolean] =
    (index, parsedValues) => Some(true),
  transform: (Int, List[String]) => Option[List[String]] =
    (index, parsedValues) => Some(parsedValues)
): Try[List[List[String]]] =
  tryProcessSourceGeneric(file, parseLine, filter, transform)

И функция generic-ified выглядит так (обратите внимание на отсутствие значений по умолчанию для параметра):

def tryProcessSourceGeneric[A, B](
  file: File,
  parseLine: (Int, String) => Option[A],
  filter: (Int, A) => Option[Boolean]
  transform: (Int, A) => Option[B]
): Try[List[B]] = {
  ???
}

И снова огромное спасибо Алексею и Ли за то, что помогли мне преодолеть это.