I've seen all the other answers to this exception but I don't think they solve my problem or may be I don't understand.
I'm trying to create a type class to extract out implementation of Command
s to CommandHandler
s
object TestMe extends App {
//COMMAND
trait Command
trait UserCommand extends Command
case class CreateUserCommand(username: String) extends UserCommand
//COMMAND HANDLER
trait CommandHandler[C <: Command] {
def processCommand(command: C): Boolean
}
trait UserCommandHandler[+C <: UserCommand] extends CommandHandler[C]
implicit object CreateUserCommandHandler extends UserCommandHandler[CreateUserCommand] {
override def processCommand(command: CreateUserCommand): Boolean = true
}
//Running UserCommand
def processCommand[C <: UserCommand](command: C)(implicit commandHandler: UserCommandHandler[C]) =
commandHandler.processCommand(command)
val createUserCommand: UserCommand = CreateUserCommand("username")
println(processCommand(createUserCommand))
}
But I keep getting the following exception
covariant type C occurs in invariant position in type [+C <: TestMe.Command]TestMe.CommandHandler[C] {
} of trait UserCommandHandler
trait UserCommandHandler[+C <: Command] extends CommandHandler[C]
^
The type C in UserCommandHandler is covariant but the type C in CommandHandler is invariant, so you cant pass the C type from the UserCommandHandler to CommandHandler
So you have 2 options -
Type C in CommandHandler trait should also be covariant.
trait CommandHandler[+C <: Command] { def processCommand[B >: C](command: B): Boolean }
Type C in UserCommandHandler should be invariant
trait UserCommandHandler[C <: UserCommand] extends CommandHandler[C]
Looking at the rest of your code, invariance seems like its good enough. Making CommandHandler covariant will require other changes to your code as well
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.