简体   繁体   中英

scala value is not a member of type parameter

I'm trying to get the hang of Scala traits and case classes. Below is a followup to this question .

Suppose I have a simple class and an object that extends it.

sealed trait Operations{
    def add(a:Double,b:Double):Double
    def multiply(a:Double,b:Double):Double
}

case object CorrectOperations extends Operations{
    def add(a:Double,b:Double):Double = a+b
    def multiply(a:Double,b:Double):Double= a*b
}

Now I have some function that will make use of any object of type Operations , such as,

def doOperations(a:Double,b:Double, op:Operations)={ op.multiply(a,b) - op.add(a,b)}.

This works well, but my question is how to generalize the types of trait Operations , so we're not just talking about Doubles . So i'd like to have generic types for trait Operations and then type specification for each object.

Using type generics, I tried

sealed trait Operations[T]{
  def add(a:T,b:T):T
  def multiply(a:T,b:T):T
}

case object CorrectOperations extends Operations[Double]{
    def add(a:Double,b:Double):Double = a+b
    def multiply(a:Double,b:Double):Double= a*b
}

def doOperations[T](a:T,b:T, op:Operations[T])={ op.multiply(a,b) - op.add(a,b) },

with a compile error at doOperations - "value - is not a member of type parameter T".

So we know that op.multiply(a,b) will return type T , and the error would indicate that type T has no .- method.

How should I be thinking about achieving this generalization of trait Operations ? Thanks

In the context of your problem, you should introduce a subtract method into your Operations trait, so that you can provide evidence that T has such a method (well it doesn't, but a method that does a subtraction from to T from another).

sealed trait Operations[T] {
    def add(a: T, b: T): T
    def multiply(a: T, b: T): T
    def subtract(a: T, b: T): T
}

case object CorrectOperations extends Operations[Double]{
    def add(a: Double, b: Double): Double = a + b
    def multiply(a: Double, b: Double): Double = a * b
    def subtract(a: Double, b: Double): Double = a - b
}

def doOperations[T](a: T, b: T, op: Operations[T]) =
    op.subtract(op.multiply(a,b), op.add(a,b))

This is basically what the Numeric trait does.

The problem you are running into is that there is no - (minus) operation in your type class to subtracting your multiply result from your add result fruitlessly looks for that operator on type T .

Try adding minus to your type class:

sealed trait Operations[T]{
  def add(a:T,b:T):T
  def multiply(a:T,b:T):T
  def minus(a:T,b:T):T
}

def doOperations[T](a:T,b:T, op:Operations[T])=
  op.minus(op.multiply(a,b) - op.add(a,b))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM