0
votes

I have this trait:

trait Delivery[T] {
  def form(): Form[T]
}

where Form is from play2 framework.

Then I have object that implements Delivery trait:

case class NewPostValidator(town: String, number: Int)

object NewPost extends Delivery[NewPostValidator]{
  def form(): Form[NewPostValidator] = Form(mapping(
    "town" -> nonEmptyText,
    "number" -> number)(NewPostValidator.apply)(NewPostValidator.unapply))
}

Now I want to write function which accepts List of objects that implements trait Delivery. And I can't write type for parameter of it. If I try to write this like

list: List[Delivery[AnyRef]]

I've got type mismatch error and if I change Delivery trait to:

trait Delivery[+T] {
    def form(): Form[T]
}

I've got Scala covariant type T occurs in invariant position error. How can I describe type for this parameter?

1
What is the exact error? As comment above suggests, you can use List[Delivery[_]]. You should not be simply throwing in covariance if you're not sure what it means.slouc

1 Answers

1
votes

I'm not sure if you want all the forms inside the method to be of the same underlying type or if you care about the return type inside Form. It would be good to understand what's going on here.

trait Delivery[T] {
  def form(): Form[T]
}

case class NewPostValidator(town: String, number: Int)

object NewPost extends Delivery[NewPostValidator]{
  def form(): Form[NewPostValidator] = Form(mapping(
    "town" -> nonEmptyText,
    "number" -> number)(NewPostValidator.apply)(NewPostValidator.unapply))

  def accept[T <: Delivery[_]](list: List[T]): List[Form[_]] = {
    list.map(_.form())
  }

}