Как определить параметр функции по умолчанию, связанный с общим параметром?
Я пытаюсь реорганизовать функцию (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]] = {
???
}
И снова огромное спасибо Алексею и Ли за то, что помогли мне преодолеть это.