I'm a Java engineer who's been slowly learning Scala recently. I've come across some sample code using Dispatch to make a simple GET request:
val request = url("http://somesite.com")
val result = Http( request OK as.String)
The problem is... I don't quite get what's going on here. First, is Http a class? or a method? Second, what's up with the parameters passed to it? I thought maybe we were passing three arguments, with Scala allowing us to omit commas. But when I tried adding commas, I got a compilation error, so that can't be right.
I'm sure this makes sense to someone fluent in Scala, but I'm not there yet and it's holding me up. I've tried looking for documentation online, but have found nothing helpful.
url
is (essentially) a method that returns a Req
object. So request
has type Req
.
Http
is a class with a companion object that has a few overloads of the apply
method. So when you see:
Http(request OK as.String)
It is actually syntactic sugar for:
Http.apply(request OK as.String)
Ok, so what's going on inside apply
? It appears as though a method named OK
is being called on request
. But looking through the API Docs, you may notice there is no such method OK
for the type Req
. There is, however, a class called RequestHandlerTupleBuilder
, which does have such a method. And there is an implicit conversion defined in the dispatch
package:
implicit def implyRequestHandlerTuple(builder: Req) =
new RequestHandlerTupleBuilder(builder)
What's happening here is that when you call request OK
, the compiler sees that request
does not have an OK
method. So it then looks for possible implicit methods that accept Req
as a parameter and return types to do have such a method. The above method is the implicit it finds, so the Req
is implicitly converted to a RequestHandlerTupleBuilder
.
Now let's look at the signature of OK
:
def OK [T](f: Response => T): (Request, OkFunctionHandler[T])
It accepts a function as a parameter. In particular, a function that accepts a Response
as a parameter, and returns some other type T
. In this case, such a function is as.String
that has type Response => String
. OK
will then return a Request
tupled with an OkFunctionHandler[T]
.
This tells me that the overload of apply
we're calling is this one:
def apply[T](pair: (Request, AsyncHandler[T])): Future[T]
(OkFunctionHandler
extends AsyncHandler
)
Looking it all in a slightly more java-like style and with type annotations, you have:
val request: Req = url("http://somesite.com")
val result: Future[String] = Http.apply(request.OK(as.String))
Using only explicit calls, it would look more like:
val result: Future[String] =
Http.apply(implyRequestHandlerTuple(request).OK(as.String))
In short, there is only one parameter being passed to Http.apply
, it's just using a point-free style to call other methods within.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With