Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala is not inferring the appropriate method

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

like image 530
opensas Avatar asked Oct 31 '12 07:10

opensas


1 Answers

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.

like image 52
Kim Stebel Avatar answered Sep 29 '22 05:09

Kim Stebel