Предположим, что у меня есть экземпляр произвольного однопараметрического класса (я буду использовать в демонстрации, но это может мне другое другое).Scala: вывод типа общего типа и аргумент типа
Я хотел бы написать обобщенную функцию, которая может принимать экземпляры (c
) и быть в состоянии понять, что общий класс (A
) и какой тип аргумент (B
), полученный класс (C
) этот экземпляр.
я придумал что-то вроде этого (тело функции не очень актуальным, но демонстрирует, что C
соответствует A[B]
):
def foo[C <: A[B], A[_], B](c: C) {
val x: A[B] = c
}
... и он компилирует, если вы вызываете его, как это :
foo[List[Int], List, Int](List.empty[Int])
... но компиляция завершается с ошибкой, если я опускаю аргументы явных типа и полагаться на умозаключения:
foo(List.empty[Int])
Ошибки я получаю:
Error:Error:line (125)inferred kinds of the type arguments (List[Int],List[Int],Nothing) do not conform to the expected kinds of the type parameters (type C,type A,type B).
List[Int]'s type parameters do not match type A's expected parameters:
class List has one type parameter, but type A has one
foo(List.empty[Int])
^
Error:Error:line (125)type mismatch;
found : List[Int]
required: C
foo(List.empty[Int])
^
Как вы можете видеть вывод типа Scala не может правильно вывести типы в этом случае (кажется, что это догадка List[Int]
вместо List
для 2-го аргумента и Nothing
вместо Int
для 3-го).
Я предполагаю, что ограничения типа для foo
Я придумал, недостаточно точные/правильные, поэтому мой вопрос заключается в том, как я мог его реализовать, поэтому Scala могла вывести аргументы?
Примечание: если это помогает, предполагается, что все потенциальные дженерики (A
s) наследуют/соответствуют некоторым общим предкам. Например, A
может быть любой коллекцией, унаследованной от Seq
.
Примечание: пример, описанный в этом вопросе, является синтетическим и является дистиллированной частью большей проблемы, которую я пытаюсь решить.
посмотреть мой комментарий на hubertp ответить –
@EugenyLoy проверить мое обновление, это то, что вам нужно? Но scalac не будет декомпрессировать C в A [_] и B, вы можете написать ребятам из вилки Scale типа scala, возможно, они будут реализовывать ее. – 4lex1v
Да, это самое близкое к тому, что мне нужно. BTW, '=: =' лучше подходит для моих целей, чем '<: <', но у меня есть идея, и это не так важно. –