Ограничение параметра типа не учитывается при использовании универсального типа с неограниченным подстановочным знаком - PullRequest
0 голосов
/ 27 февраля 2019

В моем проекте у меня есть следующее созвездие:

trait F

trait X[A <: F]

def test(x: X[_]): X[_ <: F] = x

Trait X имеет параметр типа с верхней границей F.Насколько я понимаю, типы X[_] и X[_ <: F] должны быть эквивалентны.Но scalac 2.12.5 жалуется, что одно не может быть назначено другому.

$ scalac -Xscript test test.scala 
test.scala:5: error: type mismatch;
 found   : this.X[_$1] where type _$1
 required: this.X[_ <: this.F]
def test(x: X[_]): X[_ <: F] = x
                               ^

Я не могу вспомнить ситуацию, когда это назначение делает звуковую программу несостоятельной.По каким причинам это назначение отклонено?Есть ли способ, которым разрешить такое назначение (возможно, в более сложном примере) проблематично?

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

Я могу ошибаться, но достаточно взглянуть на определение самой функции:

def test(x: X[_]): X[_ <: F] = x

единственный тип информации, который дает экзистенциальный тип, - это то, что что-то существует.и с помощью этой сигнатуры вы пытаетесь «сузить» результат функции

, чтобы показать его на практическом примере.скажем, у вас есть что-то вроде этого:

def test(x: Option[_]): Option[_ <: String]

и затем вы называете это проходящим внутри Option[Int].Вы ожидаете, что это назначение будет правильным?

val result: Option[_ <: String] = test(Some(1): Option[_])
0 голосов
/ 27 февраля 2019

Это назначение на самом деле не проблематично, и компилятор даже в некотором роде это знает, потому что следующая реализация компилируется без проблем:

trait F
trait X[A <: F]
def test(x: X[_]): X[_ <: F] = x match { case q: X[t] => q }

Если вы дадите программе проверки типа некоторую слабость, позволив емуВыведите более точные границы для переменной типа t, в конечном итоге выяснится, что t должен быть подтипом F, а затем позволит вам вернуть значение q (которое совпадает с x)без жалоб.Он не делает этого по умолчанию по некоторым нелогичным причинам , которые , вероятно, как-то связаны с совместимостью с подстановочными символами Java .

(снова удаленоМое первоначальное предположение не выглядело слишком далеко, и, учитывая ссылку Дмитрия Митина , по сравнению с ним оно даже не выглядит слишком расплывчатым.

...