user830818
user830818

Reputation: 417

Return type for this scala method : String vs Any

 def loop2 (arr: List[String]) : List[String]= {
   arr.map(ele =>
      if (ele.startsWith("2")) ele)
 }

I thought that the method should return a List[String], but compiler says it should return List[Any].

Anonymous function inside the map can return either a String or nothing, so that means the the output can be empty list or List[String].

Please explain why return type should be List[Any]

Upvotes: 0

Views: 156

Answers (2)

Michael Zajac
Michael Zajac

Reputation: 55569

It seems like you're trying to filter out the elements that don't start with "2" ? If that is the case, you should use filter:

def loop2(arr: List[String]): List[String] = arr.filter(e => e.startsWith("2"))

Or

def loop2(arr: List[String]): List[String] = arr.filter(_.startsWith("2"))

The problem with the anonymous function ele => if (ele.startsWith("2")) ele) is that you don't handle the else case. An if without the else automatically makes the else return Unit, which then forces the common type to be Any.

As seen in the Scala Language Specification:

A short form of the conditional expression eliminates the else-part. The conditional expression if (e1) e2 is evaluated as if it was if (e1) e2 else ().

Upvotes: 5

Ben Reich
Ben Reich

Reputation: 16324

You need an else with your if for the compiler to figure out the type you're talking about. As it stands, it assumes the else side is () so the only deducible type is Any.

def loop2 (arr: List[String]) : List[String]= {
   arr.map(ele => if (ele.startsWith("2")) ele else "")
 }

It seems you're actually trying to filter:

def loop2 (arr: List[String]) : List[String]= {
   arr.filter(ele => ele.startsWith("2"))
 }

Or even more idiomatically:

def loop2 (arr: List[String]) : List[String]= {
   arr.filter(_.startsWith("2"))
}

Upvotes: 1

Related Questions