I would like to achieve the following functionality:
case class ValidatorClean[+A](apply: A => A)
implicit val traversableValidatorClean = ValidatorClean[Traversable[String]](_.map(_.trim))
so that traversableValidatorClean
gets picked whenever a ValidatorClean[Seq[String]]
or ValidatorClean[List[String]]
is needed, for example.
However, this doesn't compile, with the error
covariant type A occurs in contravariant position in type => A => A of value apply
I understand that a function is contravariant in its input and covariant in its output, but I want A
to behave invariantly in apply
. That is, the function in apply
will always return the exact same type as its input.
Can this be achieved?
It doesn't make sense for ValidatorClean
to be covariant.
Lets say you have:
abstract class Animal
object Animal {
def validate[A <: Animal : ValidatorClean](animal: A): Animal =
implicitly[ValidatorClean[A]].apply(animal)
}
class Cat {
def canMeow: Boolean = ???
}
class Dog {
def canBark: Boolean = ???
}
By making ValidatorClean
covariant, you're saying that ValidatorClean[Dog]
is a sub-type of ValidatorClean[Animal]
, which means that if you need a ValidatorClean[Animal]
, you will also accept a ValidatorClean[Dog]
or ValidatorClean[Cat]
for that matter.
So let's suppose we have an Animal
, but we don't know it's sub-type.
val unknown: Animal = new Dog // perhaps the Animal really came from a List
Now I write:
Animal.validate(unknown)
What happens? If there is an implicit ValidatorClean[Dog]
available, validate
will gladly accept it. Perhaps it looks like:
implicit validateDog = ValidatorClean[Dog](dog => if (dog.canBark) dog else ???)
But how can this function that accepts a Dog
and calls canBark
also process an arbitrary Animal
? It can't.
Similarly, a ValidatorClean[Traversable[String]]
would also resolve for a ValidatorClean[Any]
, even though Any
does not have a map
method, so it cannot work.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.