Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why scala can't infer the type in a partial method?

See this example:

def hello(a:String, b:String) = println(a + ":" + b)
val m1 = hello("aaa", _ )
m1("bbb")

It can't be compiled, that I need to add the type to the partial method:

val m1 = hello("aaa", _: String)

Why scala doesn't know the 2nd parameter of method hello is String?

like image 420
Freewind Avatar asked Aug 19 '11 17:08

Freewind


2 Answers

Scala's type inference is flow based. Methods and functions need explicit parameter types, which are used to infer other types. The parameter types cannot be inferred from method or function body. Sometimes, however, the parameter types are known from external context, and then don't have to be labeled. Two examples,

val f: String => Unit = hello("aaa", _)
val s = Seq(1,2).map(_+1) // Seq[Int].map expects a function of Int argument type

Below is a quote from Martin Odersky about the limitations of Scala's type inference compared to, say, ML and Haskell. Challenges include Scala's overloading, record selection, and subtyping, as well as the need to keep things simple,

The reason Scala does not have Hindley/Milner type inference is that it is very difficult to combine with features such as overloading (the ad-hoc variant, not type classes), record selection, and subtyping. I’m not saying impossible — there exist a number of extensions that incorporate these features; in fact I have been guitly of some of them myself. I’m just saying it’s very difficult to make this work well in practice, where one needs to have small type expressions, and good error messages. It’s not a shut case either — many researchers are working on pushing the boundaries here (look for instance at Remy’s MLF). But right now it is a tradeoff of better type inferencing vs better support for these features. You can make the tradeoff both ways. The fact that we wanted to integrate with Java tipped the scales in favor of subtyping and away from Hindley/Milner.

Source: comment under post Universal Type Inference is a Bad Thing.

like image 164
Kipton Barros Avatar answered Sep 28 '22 08:09

Kipton Barros


To put it very simply, Scala uses the parameter types to search for the appropriate method, not method type to deduce the type of the parameters.

To do what you want, it would have to search for all possible calls to hello with two parameters, the first of them String -- which might include implicit conversions -- and then, if a single most specific option is found, use it to infer the type of that second parameter. It would have to do this in addition to all that it does already, slowing down even more what is already a rather slow compilation. Not impossible, but it doesn't do that.

like image 39
Daniel C. Sobral Avatar answered Sep 28 '22 09:09

Daniel C. Sobral