Reputation: 63415
I have the following method
def show[E: Writes, T: Writes](block: RequestWithUser[AnyContent] => Either[E, T]): Action[AnyContent] = {
withErr(block)
}
which I use like this from a controller:
def show(id: Long) = CrudAuthAction.show { request =>
IdeaType.findByIdWithErr(id)
}
And I want the request method to be optional, so I defined another signature for the same method:
def show[E: Writes, T: Writes](block: => Either[E, T]): Action[AnyContent] = {
withErr(request => block)
}
And it works fine, I can omit the request param
But when I try to do the same with this other method
def list[T: Writes](block: RequestWithUser[AnyContent] => T): Action[AnyContent] = {
fromRequest(block)
}
def list[T: Writes](block: => T): Action[AnyContent] = {
fromRequest(request => block)
}
When I want to use it like this:
def list = CrudAuthAction.list { request =>
IdeaType.find(request.queryString)
}
it tells me that request is missing parameter type, and I have to specify it like this:
def list = CrudAuthAction.list { request: RequestWithUser[AnyContent] =>
I don't see what's different from the first case, but scala can't seem to infer the proper type of request...
The only difference I see is that in the first case, the block is returning an Either[E, T], but in the second case is returning just a generic T...
Upvotes: 6
Views: 125
Reputation: 42047
The problem is that in the second example the compiler does not know which of the overloaded methods to pick, because T could well be a function type. Since Either
is clearly not a function, it works in the first case.
To work around this issue, you could change the second method to
def list[T: Writes](block: => Foo[T]): Action[AnyContent] = {
fromRequest(request => block.v)
}
With Foo defined like that:
case class Foo[T](val v:T)
Unfortunately, adding an implicit conversion to Foo breaks things again, unless you create an implicit conversion for each type in the Writes
type class.
Upvotes: 5