Dotan
Dotan

Reputation: 7622

Scala: type check on yield that may return an empty list

I have to following code in Scala, that's meant to return sentences.

val x: List[Word] = for (word <- words) yield {
  if (word.isLegit()) sentenceStartingWith(word)
}

I'm getting an error because the type of x is not List[word] but Any (because it may not yield anything). Casting didn't help.

The simple fix that came to mind was

val x: List[Word] = for (word <- words) yield {
  if (word.isLegit()) sentenceStartingWith(word)
  else List[Word]()
}

But this returns a list with a lot of empty lists as members. How can I get the behavior I want, which is to return a List[word] with all the items if finds (or empty if it finds none)

Upvotes: 3

Views: 463

Answers (2)

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149598

I'm getting an error because the type of x is not List[word] but Any

The compiler is inferring what you're trying to do. What it sees is that you only return a value when your if statement is matched, thus it implicitly returns List[Any] (via List.canBuildFrom[Any]) for anything that doesn't match the predicate. Thus, the common supertype of both Seq[Any].

One possible way of doing this would be using a guard to filter out words first:

val x: List[Word] = for (word <- words if word.isLegit()) yield sentenceStartingWith(word)

This is equivalent to:

val x = words.withFilter(_.isLegit()).map(word => sentenceStartingWith(word))

Note methods in Scala are camelCase, and class names are PascalCase.

Upvotes: 7

Dhirendra
Dhirendra

Reputation: 309

Try This

  val x: List[word] = for (word <- words  if (word.isLegit())) yield {word}

Upvotes: 2

Related Questions