Scala Upper Bounds : value is not a member of type parameter
Asked Answered
D

1

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.

Digit answered 9/2, 2012 at 20:5 Comment(0)
T
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)
}
Theadora answered 9/2, 2012 at 20:19 Comment(6)
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 classDigit
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 CalcDigit
@George, regarding the error: you still have that S with recalc. I suggested otherwise.Theadora
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 {Digit
@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.Theadora
The code I suggested compiles. Both snippets.Theadora

© 2022 - 2024 — McMap. All rights reserved.