Without syntax sugar, what you have is:
(JsPath \ "lat").read[Double](min(-90.0) keepAnd max(90.0))
.and( (JsPath \ "long").read[Double](min(-180.0) keepAnd max(180.0)) )
.apply(Location.apply _)
The parentheses around the (... and ...)
in your post are just like the parentheses in an expression like (1 + 2) / 3
. They were used so the and
method could be called like an operator and then call a method on the result of that and
method. Nothing really special there.
The parentheses around Location.apply _
are because you are passing Location.apply _
as an argument to a function. You are technically calling the (... and ...)
object's apply
method, and omitting the word "apply" thanks to a Scala syntax sugar.
In scala, objects with an apply
method can be treated as functions thanks to the syntax sugar, i.e. the following two statements are equivalent:
foo.apply(1)
foo(1) // equivalent
Note that this is not "currying" as the other answer states.
Currying is a way to represent a function with multiple arguments as a series of "functions which return functions", e.g.
def myFunc(a: Int, b: Int, c: Int) = a + b + c
val sum = myFunc(1, 2, 3)
def myCurriedFunc(a: Int)(b: Int)(c: Int) = a + b + c
val sum = myCurriedFunc(1)(2)(3)
val addOneAndTwo = myCurriedFunc(1)(2)
val sumAgain = addOneAndTwo(3)