Question

Let's declare a def and an equivalent function as a val:

scala> def optional(x:Int):Option[String] = None
optional: (x: Int)Option[String]

scala> val optional2:(Int)=>Option[String] = (i:Int) => None
optional2: Int => Option[String] = <function1>

Now why doesn't this work?

scala> List(1).flatMap(optional2)
<console>:9: error: type mismatch;
 found   : Int => Option[String]
 required: Int => scala.collection.GenTraversableOnce[?]
              List(1).flatMap(optional2)
                              ^

While both of these do?

scala> List(1).flatMap(optional)
res4: List[String] = List()

scala> List(1).flatMap(optional2(_))
res5: List[String] = List()

Since Option is not a subtype of GenTraversableOnce, I think this must have something to do with implicits, but I can't figure out what exactly it is. I am using Scala 2.9.1.

Was it helpful?

Solution

The implicit conversion Option.option2Iterable is what makes List(1).flatMap(optional) and List(1).flatMap(optional2(_)) work.

Your issue can be boiled down to the implicit conversion not being picked up:

scala> val optional2:(Int)=>Option[String] = (i:Int) => None
optional2: Int => Option[String] = <function1>

scala> (optional2(_)): Function[Int, Iterable[String]]
res0: Int => Iterable[String] = <function1>

scala> (optional2): Function[Int, Iterable[String]]
<console>:9: error: type mismatch;
 found   : Int => Option[String]
 required: Int => Iterable[String]

When you use the underscore, the compiler attempts to type the function and provide the necessary implicit conversion. When you just provide optional2, there is no implicit conversion that applies.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top