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.