Верхние границы Scala: значение не является членом параметра типа

Почему Price не может найти значение атрибута в SeqValue? Это кажется настолько простым, что должно работать.

Я получаю сообщение об ошибке

[error]   .... value value is not a member of type parameter SeqValue
[error]   def recalc[SeqValue](input:SeqValue) = Price(1 + seq, input.value)    

для следующего кода

sealed trait SeqValue {
  def seq:Int
  def value:Float
  override def toString = ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE)
}

sealed trait Calc {
  type S <: SeqValue
  def recalc[S](input:S):SeqValue
}

case class Price(seq:Int=0, value:Float=.0f) extends SeqValue with Calc {
  def recalc[SeqValue](input:SeqValue) = Price(1 + seq, input.value)
}

Идея состоит в том, что вы можете пересчитать объект цены и передать объект любого типа, который реализует SeqValue, потому что SeqValue имеет значение.


person George    schedule 09.02.2012    source источник


Ответы (1)


Член типа S в Calc затеняется параметром типа S метода recalc.

Вторая ошибка: абстрактный тип S должен быть определен в классе Price.

Следующее должно работать:

sealed trait SeqValue {
  def seq:Int
  def value:Float
  override def toString = ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE)
}

sealed trait Calc {
  type S <: SeqValue
  def recalc(input:S):SeqValue
}

case class Price(seq:Int=0, value:Float=.0f) extends SeqValue with Calc {
  type S = SeqValue
  def recalc(input:SeqValue) = Price(1 + seq, input.value)
}

Изменить: (в ответ на комментарий)

Я не понимаю, что именно вы пытаетесь сделать, но вы можете выделить определение типа в отдельном свойстве миксина.

trait SAsSeqValue {
  type S = SeqValue
}

case class Price(seq:Int=0, value:Float=.0f) extends SeqValue with Calc with SAsSeqValue {      
  def recalc(input:SeqValue) = Price(1 + seq, input.value)
}
person missingfaktor    schedule 09.02.2012
comment
Спасибо, это сработало! У меня есть много классов, которые реализуют Calc. Есть ли способ переопределить класс/черты, чтобы мне не нужно было добавлять тип S = SeqValue в каждый класс? - person George; 10.02.2012
comment
на самом деле, похоже, это не сработало class Price needs to be abstract, since method recalc in trait Calc of type [S](input: S)com.quasiquant.SeqValue is not defined [error] case class Price(seq:Int=0, value:Float=.0f) extends SeqValue with Calc - person George; 10.02.2012
comment
@ Джордж, по поводу ошибки: у тебя все еще есть S с recalc. Я предложил другое. - person missingfaktor; 10.02.2012
comment
Спасибо за вашу помощь. Я использую отредактированный код, который вы предложили, но. [error] /Users/gsward/Development/QuasiQuant/src/main/scala/com/quasiquant/SeqValue.scala:51: class Price needs to be abstract, since method recalc in trait Calc of type [S](input: S)com.quasiquant.SeqValue is not defined [error] case class Price(seq:Int=0, value:Float=.0f) extends SeqValue with Calc with SAsSeqValue { - person George; 10.02.2012
comment
@ Джордж, я сомневаюсь, что ты используешь код, который я предложил. В вашем сообщении об ошибке говорится, что у вас есть параметр типа S в методе recalc, хотя я предложил его удалить. - person missingfaktor; 10.02.2012
comment
Код, который я предложил, компилируется. Оба фрагменты . - person missingfaktor; 10.02.2012