Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Methods versus Function and implicits in Scala

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.

like image 606
Kim Stebel Avatar asked Mar 18 '12 18:03

Kim Stebel


People also ask

What is the difference between method and function in Scala?

Difference between Scala Functions & Methods: Function is a object which can be stored in a variable. But a method always belongs to a class which has a name, signature bytecode etc. Basically, you can say a method is a function which is a member of some object.

What is Implicits in Scala?

Implicit parameters are the parameters that are passed to a function with implicit keyword in Scala, which means the values will be taken from the context in which they are called.

What are methods in Scala?

A Scala method is a part of a class which has a name, a signature, optionally some annotations, and some bytecode where as a function in Scala is a complete object which can be assigned to a variable. In other words, a function, which is defined as a member of some object, is called a method.

Why does Scala have Implicits?

The implicit system in Scala allows the compiler to adjust code using a well-defined lookup mechanism. A programmer in Scala can leave out information that the compiler will attempt to infer at compile time. The Scala compiler can infer one of two situations: A method call or constructor with a missing parameter.


1 Answers

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.

like image 170
huynhjl Avatar answered Sep 28 '22 14:09

huynhjl