Обмен верхней границы параметра типа на параметр доказательства - PullRequest
6 голосов
/ 02 января 2012

Я хочу ослабить ограничения на параметр типа признака и вместо этого наложить их на метод в форме параметра доказательства.Учитывая некоторые настройки скелета:

trait State[Repr]
object Observer {
  def apply[Repr <: State[Repr]](reader: Reader[Repr]): Observer[Repr] = 
    new Observer[Repr] {}
}
trait Observer[A]
trait Reader  [A]

Это работает:

trait StateX[Repr <: StateX[Repr]] extends State[Repr] { 
  protected def reader: Reader[Repr]
  def observe: Observer[Repr] = Observer(reader)
}

И это не так:

trait StateY[Repr] extends State[Repr] { 
  protected def reader: Reader[Repr]
  def observe(implicit ev: Repr <:< State[Repr]): Observer[Repr] = Observer(reader)
}

С сообщением "inferred type arguments [Repr] do not conform to method apply's type parameter bounds [Repr <: State[Repr]]".Поскольку свидетельство ev предполагает эту конформацию, мне интересно, как StateY можно исправить.

Ответы [ 2 ]

6 голосов
/ 02 января 2012

Ваша проблема в том, что, хотя свидетельство формы A <:< B подразумевает, что значение типа A может быть преобразовано в значение типа B, оно не подразумевает A <: B ... действительно,Основная причина использования ограничения типа или представления, а не ограничения обычного типа, заключается именно в том, что такое отношение подтипа не выполняется.

Следовательно, ограничение в StateY, Repr <:< State[Repr] не являетсядостаточно, чтобы удовлетворить оценку Repr <: State[Repr] для Observer 'apply метода.Учитывая, что вы хотите ослабить ограничение на параметр типа StateX, ваша единственная возможность - ослабить ограничение на параметр типа метода apply соответственно.Это дает вам что-то вроде следующего, используя ограничение вида вместо обычного ограничения типа

object Observer {
  def apply[Repr <% State[Repr]](reader : Reader[Repr]) : Observer[Repr] =
    new Observer[Repr] {}
}

или, альтернативно,

object Observer {
  def apply[Repr](reader : Reader[Repr])
                 (implicit ev : Repr <:< State[Repr]) : Observer[Repr] =
    new Observer[Repr] {}
}

, если вы предпочитаете использовать ограничения повсюду.*

5 голосов
/ 02 января 2012

Данные свидетельствуют о том, что Repr может быть преобразовано в State[Repr]. Это ничего не говорит о том, что можно сделать с помощью Reader [Repr].

Не существует общего метода (независимого от T) для преобразования T [A] в T [B] при условии A => B. Это может быть возможно для ковариантного T, но в языке такого нет.

...