playframework/playframework — pull request #1844 by dwhjames (2013-10-17 04:34:53+00:00)
Title: Make ActionBuilder covariant

ActionBuilder is more flexible if it is declared to be covariant rather than invariant in its higher kinded type R.

`R` only appears in covariant positions `ActionBuilder`, for example:
```scala
def apply(block: R[AnyContent] => Result): Action[AnyContent]
```
`(R[AnyContent] => Result)` is in a contravariant position and `R[A]` is the contravariant position of the function type, which overall makes `R` covariant.

Here’s an example of what I would do with a covariant `ActionBuilder`:
```scala
trait FlexibleActionBuilderController extends Controller {

protected def customAction: ActionBuilder[Request]

def index = customAction.async { request =>
…
}

}

object UnsecuredController extends FlexibleActionBuilderController {
override def customAction = Action
}

object SecuredController extends FlexibleActionBuilderController {
override def customAction =
new play.api.mvc.Security.AuthenticatedBuilder(req => myAuthenticationMethod(req))
}
```

`SecuredController` won’t type check with an invariant `ActionBuilder`. My current workaround is to force the upcast with `asInstanceOf`.