0

Why can the Price not find the attribute value on the SeqValue? It seems so simple that is should work.

Im getting the error

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

for the following code

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)
}

The idea is that you can recalc on the price object, and pass in any type of object that implements SeqValue, because SeqValue has a value.

George
  • 17
  • 1
  • 6

1 Answers1

3

The type member S in Calc is getting shadowed by type parameter S of recalc method.

Second mistake: The abstract type S will have to be defined in class Price.

The following should work:

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)
}

Edit: (in response to the comment)

I don't understand what you're exactly trying to do, but you could separate out the type definition in a separate mixin trait.

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)
}
missingfaktor
  • 90,905
  • 62
  • 285
  • 365
  • Thanks it worked! I have a lot classes that implement Calc. Is there a way to redefine the class/traits so that i dont have to add type `S = SeqValue` in every class – George Feb 09 '12 at 20:31
  • actually, it doesn't seemed to have worked `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` – George Feb 09 '12 at 20:38
  • @George, regarding the error: you still have that `S` with `recalc`. I suggested otherwise. – missingfaktor Feb 09 '12 at 20:39
  • Thanks for your help. I am using the edited code you suggested, but. `[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 {` – George Feb 09 '12 at 20:45
  • @George, I doubt you are running the code I suggested. Your error message says you have a type parameter `S` on method `recalc` while I have suggested to remove it. – missingfaktor Feb 09 '12 at 20:48
  • The code I suggested compiles. [Both](http://ideone.com/bcgU2) [snippets](http://ideone.com/thNuW). – missingfaktor Feb 09 '12 at 20:49