问题
After seeing the method signature of map in scala as
def map[A, B](l: List[A])(f: A => B): List[B] = ???
my layman undersanting of [A, B] in above is that they signal the method that we'll be exclusively working with generic Type A and B in the defined method.
Now I go on to implement a method to add values from two lists consquetively (basically zipWith) using similar coding pattern.
def addCorresponding[Int](l1: List[Int],
l2: List[Int]): List[Int] =
(l1, l2) match {
case (_, Nil) => Nil
case (Nil, _) => Nil
case (x::xs, y::ys) => {
List((x + y)) ++ addCorresponding(xs, ys)
}
}
but get this error while adding the elements in the last match: type mismatch found: Int Required: String
Removeing the [Int] from the mehtod sigature fixes this error.
I'm sure there are holes in my understanding of generic Types and when to add them to the method signature. I'd appreciate if someone can walk me through this and explain why the addCorresponding
method with [Int] errors out but works fine without it?
回答1:
The generic method (taking a type parameter) would be
def addCorresponding[A](l1: List[A], l2: List[A]): List[A]
or, if the lists can have different types of elements
def addCorresponding[A, B, C](l1: List[A], l2: List[B]): List[C]
If you implement a method that works on a concrete type Int
, then your method is no longer generic:
def addCorresponding(l1: List[Int], l2: List[Int]): List[Int]
In other words, you apply a concrete type Int
here to List[_]
instead of an abstract type parameter. If you write
def addCorresponding[Int](l1: List[Int], l2: List[Int]): List[Int]
then you "shadow" the concrete type Int
with an abstract type parameter Int
that happens to have the same name; but technically you are writing the generic method
def addCorresponding[XXX](l1: List[XXX], l2: List[XXX]): List[XXX]
If you want to keep your method generic but perform certain operations on elements of type A
, you may need a type class, for example Numeric
to arithmetically add elements
def addCorresponding[A](l1: List[A],
l2: List[A])(implicit num: Numeric[A]): List[A] =
(l1, l2) match {
case (_, Nil) => Nil
case (Nil, _) => Nil
case (x::xs, y::ys) =>
List((num.plus(x, y))) ++ addCorresponding(xs, ys)
}
来源:https://stackoverflow.com/questions/65452344/difference-b-w-methodint-vs-method-in-scala