Understanding type inferrence in Scala

I wrote the following simple program:

import java.util.{Set => JavaSet}
import java.util.Collections._

object Main extends App {
    def test(set: JavaSet[String]) = ()

    test(emptySet()) //fine
    test(emptySet) //error
}

DEMO

And was really surprised the the final line test(emptySet) was not compiled. Why? What is the difference between test(emptySet()) ? I thought in Scala we could omit parenthesis freely in such cases.


See Method Conversions in Scala specification:

The following four implicit conversions can be applied to methods which are not applied to some argument list.

Evaluation

A parameterless method m of type => T is always converted to type T by evaluating the expression to which m is bound.

Implicit Application

If the method takes only implicit parameters, implicit arguments are passed following the rules here.

Eta Expansion

Otherwise, if the method is not a constructor, and the expected type pt is a function type (Ts′)⇒T′, eta-expansion is performed on the expression e.

Empty Application

Otherwise, if e has method type ()T, it is implicitly applied to the empty argument list, yielding e().

The one you want is "Empty Application", but it's only applied if none of the earlier conversions are, and in this case "Eta Expansion" happens instead.

EDIT: This was wrong and @Jasper-M's comment is right. No eta-expansion is happening, "Empty Application" is just inapplicable to generic methods currently.

链接地址: http://www.djcxy.com/p/94486.html

上一篇: 如何将文件上传到Node.js中的GCloud?

下一篇: 理解Scala中的类型推理