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...
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.
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