Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

type inference in fold left one-liner?

I was trying to reverse a List of Integers as follows:

List(1,2,3,4).foldLeft(List[Int]()){(a,b) => b::a}

My question is that is there a way to specify the seed to be some List[_] where the _ is the type automatically filled in by scala's type-inference mechanism, instead of having to specify the type as List[Int]?

Thanks

like image 401
sc_ray Avatar asked Nov 21 '12 06:11

sc_ray


1 Answers

Update: After reading a bit more on Scala's type inference, I found a better answer to your question. This article which is about the limitations of the Scala type inference says:

Type information in Scala flows from function arguments to their results [...], from left to right across argument lists, and from first to last across statements. This is in contrast to a language with full type inference, where (roughly speaking) type information flows unrestricted in all directions.

So the problem is that Scala's type inference is rather limited. It first looks at the first argument list (the list in your case) and then at the second argument list (the function). But it does not go back.

This is why neither this

List(1,2,3,4).foldLeft(Nil){(a,b) => b::a}

nor this

List(1,2,3,4).foldLeft(List()){(a,b) => b::a}

will work. Why? First, the signature of foldLeft is defined as:

 foldLeft[B](z: B)(f: (B, A) => B): B 

So if you use Nil as the first argument z, the compiler will assign Nil.type to the type parameter B. And if you use List(), the compiler will use List[Nothing] for B.

Now, the type of the second argument f is fully defined. In your case, it's either

(Nil.type, Int) => Nil.type

or

(List[Nothing], Int) => List[Nothing]

And in both cases the lambda expression (a, b) => b :: a is not valid, since its return type is inferred to be List[Int].


Note that the bold part above says "argument lists" and not "arguments". The article later explains:

Type information does not flow from left to right within an argument list, only from left to right across argument lists.

So the situation is even worse if you have a method with a single argument list.

like image 84
rolve Avatar answered Sep 17 '22 14:09

rolve