Reputation: 23
I'm having a hard time understanding the scala compiler here. I'm passing three higher order functions to a superclass like this:
... extends Arithmetic(Math.pow(-_,_), Math.log(_)/Math.log(_), Math.pow(_,_))
The first function doesn't compile, the last function compiles, the only difference being the minus sign. The compiler gives the following warning:
error: wrong number of parameters; expected = 2
which is confusing, as there are two underscores. I will probably have to ditch the underscore syntax, but I want to understand why this happens. I have also tried
Math.pow(0-(_),_) Math.pow(0.-(_),_) Math.pow(0.0.-(_),_)
which all give the same error. Finally
Math.pow(-(_:Double),_:Double)
gives a new error
error: type mismatch;
found : Double => Double
required: Double
which looks more like an actual error instead of me violating syntax. Now my next thought was, "apparently the underscore syntax doesn't work if there are functions within others". But looking at the second function Math.log(_) / Math.log(_)
, which to my knowledge is converted to Math.log(_)./(Math.log(_))
, and compiles, this makes no sense, as here the partially applied log
function is passed into ./(...)
Also, the expected type of the function, defined in the superclass Arithmetic
is (Double,Double) => Double
, so why does the type problem only surface after I explicitely declared the types?
Color me confused.
Upvotes: 2
Views: 559
Reputation: 53348
Math.pow(_,_)
means (x,y) => Math.pow(x,y)
whereas Math.pow(-_,_)
means y => Math.pow(x => -x,y)
. Math.log(_)/Math.log(_)
is an infix method call, it means the same as Math.log(_)./(Math.log(_))
and therefore (x,y) => Math.log(x)./(Math.log(y))
.
See the StackOverflow Scala Tutorial in Chapter 21 "Functions/Function literals" and the subpoints "Placeholder syntax" to find more detailed explanations about how the underscores are parsed.
Upvotes: 1