Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding type inferrence in Scala

Tags:

methods

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.

like image 492
St.Antario Avatar asked Dec 20 '16 07:12

St.Antario


People also ask

How does Scala determine types when they are not specified?

Non-value types capture properties of identifiers that are not values. For example, a type constructor does not directly specify a type of values. However, when a type constructor is applied to the correct type arguments, it yields a first-order type, which may be a value type.

What is type in Scala?

Scala is a statically typed programming language. This means the compiler determines the type of a variable at compile time. Type declaration is a Scala feature that enables us to declare our own types.

What is type annotation in Scala?

Type annotations are being explored in a series on Type-class because, as explained in the first post, in Scala, Type-class is a pattern which is encoded using various language features. Type annotations happen to be one of the language features that is needed.

How does Java type inference work?

Type inference is a Java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable.


1 Answers

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.

like image 143
Alexey Romanov Avatar answered Oct 01 '22 01:10

Alexey Romanov