Question

If I have something like a List[Option[A]] and I want to convert this into a List[A], the standard way is to use flatMap:

scala> val l = List(Some("Hello"), None, Some("World"))
l: List[Option[java.lang.String]] = List(Some(Hello), None, Some(World))

scala> l.flatMap( o => o)
res0: List[java.lang.String] = List(Hello, World)

Now o => o is just an identity function. I would have thought there'd be some way to do:

l.flatMap(Identity) //return a List[String]

However, I can't get this to work as you can't generify an object. I tried a few things to no avail; has anyone got something like this to work?

Was it helpful?

Solution

There's an identity function in Predef.

l flatMap identity[Option[String]]

> List[String] = List(Hello, World)

A for expresion is nicer, I suppose:

for(x <- l; y <- x) yield y

Edit:

I tried to figure out why the the type parameter (Option[String]) is needed. The problem seems to be the type conversion from Option[T] to Iterable[T].

If you define the identity function as:

l.flatMap( x => Option.option2Iterable(identity(x)))

the type parameter can be omitted.

OTHER TIPS

FWIW, on Scala 2.8 you just call flatten on it. Thomas has it mostly covered for Scala 2.7. He only missed one alternative way of using that identity:

l.flatMap[String](identity)

It won't work with operator notation, however (it seems operator notation does not accept type parameters, which is good to know).

You can also call flatten on Scala 2.7 (on a List, at least), but it won't be able to do anything without a type. However, this works:

l.flatten[String]

You could just give the type inferencer a little help:

scala> val l = List(Some("Hello"), None, Some("World"))
l: List[Option[java.lang.String]] = List(Some(Hello), None, Some(World))

scala> l.flatten[String]
res0: List[String] = List(Hello, World)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top