Scala类型不匹配问题:期望Int而非泛型A,求原因
Let's break down what's going wrong here, then fix the code properly.
First, the immediate error you're seeing:
[ERROR] found : A
[INFO] required: Int
[INFO] case h::tail => flattenIt(tail, outList(h))
The problem is outList(h)—you're trying to use h (which is of type A) as an argument to outList.apply, but Scala's List.apply method expects an integer index to fetch an element from the list. That's why the compiler is yelling about needing an Int instead of your type A. Your intent here was to add h to the result list, not fetch an element using h as a key.
Beyond that, your code has a few other logic issues that would prevent it from working even after fixing that line:
- Your base case
case Nil => Nilignores the accumulatoroutListentirely—you should return the accumulated results (adjusted for order, since we'll build the list backwards). - In the sublist case, you're calling
flattenIt(h, outList)twice and concatenating them, which would duplicate the flattened sublist. You need to flatten the sublist once, then continue with the rest of the input list. - Due to JVM type erasure,
case (h : List[A])won't reliably match nested lists of typeA—we need to adjust the input type to handle mixed elements (values and sublists).
Corrected Code
Here's a working, tail-recursive version that fixes all these issues:
def flattenList[A](list: List[Any]): List[A] = { // Use @tailrec to ensure the compiler optimizes this to a loop @scala.annotation.tailrec def flattenIt(inList: List[Any], outList: List[A]): List[A] = inList match { // When we've processed all elements, reverse the accumulator to get the correct order case Nil => outList.reverse // Handle nested sublists: flatten the sublist first, then process the remaining elements case (sublist: List[_]) :: remaining => flattenIt(remaining, flattenIt(sublist, outList)) // Handle individual elements: add them to the front of the accumulator case element :: remaining => flattenIt(remaining, element.asInstanceOf[A] :: outList) } flattenIt(list, Nil) } // Test it with your nested list val nestedList = List(1, List(2, 3, 4), 5, List(6, 7, 8), 9, 10) println(flattenList[Int](nestedList)) // Output: List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Key Fixes Explained
- Input Type: We changed the input to
List[Any]because your nested list contains a mix of values (Int) and sublists (List[Int]). This lets us match both types in the pattern matching. - Accumulator Handling: We build the result list by adding elements to the front of
outList(more efficient for tail recursion), then reverse it at the end to get the correct order. - Sublist Processing: When we hit a nested list, we recursively flatten it first, then pass that updated accumulator to process the rest of the input list.
- Type Casting:
element.asInstanceOf[A]safely casts the element to your target typeA—this is acceptable here since you know the input list only containsAand nested lists ofA. If you want stricter type safety, you could add runtime checks, but this works for most common use cases.
内容的提问来源于stack exchange,提问作者Amber

