Why can't scala specify the type of missing parameters in a partial application?

consider this:

scala> def sum(x:Int,y:Int) = x+y sum: (x: Int, y: Int)Int scala> sum(1,_:String) <console>:9: error: type mismatch; found : String required: Int sum(1,_:String) 

Scala seems to know the exact type of _ in sum(1,_) , but you should say sum(1,_:Int) . What for?

Apparently Scala randomly (?) Selects one:

 scala> def sum(x:Int,y:String) = 1 sum: (x: Int, y: String)Int scala> def sum(x:Int,y:Double) = 1 sum: (x: Int, y: Double)Int scala> class Ashkan defined class Ashkan scala> sum(1,_:Ashkan) <console>:10: error: type mismatch; found : Ashkan required: Double sum(1,_:Ashkan) 
+6
source share
3 answers

Judging by this issue , it looks like they could have done it, but in the general case it would have been too difficult with respect to the benefits that it would have provided. The reason this would be difficult at all is the possibility of overloaded methods. In the case when you also had:

 def sum (x : Int , y : Double ) = x + y 

in the field, it would be ambiguous what function you had in mind without a type specification. In the case where there is no overload, type inference can easily understand this, but I understand that they do not feel that it is worth it to provide this particular case.

In short, this seems to be a practical, not theoretical, limitation.

I believe that the error message is generated by simply capturing the first function with the corresponding name and arity, which in the case of an unloaded function gives the impression that it fully justified the types.

+1
source

I would suggest that this is an extension of this sidebar or box in the Good Book, which expresses the Least Surprise Principle:

http://www.artima.com/pins1ed/functions-and-closures.html#8.7

Or don't call it β€œLeast Surprise,” but fewer than two surprises.

Consider the following case when you ask the compiler to choose between two inherited functions. If the usual overload rules apply, he will select the method defined in the subclass. But is that a good policy?

 scala> class Foo { | def f(x: Int, y: Int) = x + y | } defined class Foo scala> class Bar extends Foo { | def f(x: Int, y: String) = x + y.toInt | } defined class Bar scala> class Baz extends Bar { | val f = super.f(1, _) // overloading says f(Int,String), did you mean it? | } 

In an object-oriented world, there are too many ways to surprise yourself, so there is a small tax on payment. Income tax.

(Note that in this example, resolution overload is possible, but by specifying f(1, _: MyWhatever) , we determined what applicability means.)

+1
source

Do the answers to this question shed light on it for you? This seems like inconsistency, as @oxbow_lakes answer testifies.

0
source

Source: https://habr.com/ru/post/927483/


All Articles