I'm relatively new to Scala and I'm having issues with generic type parameters. I'm implementing command pattern for certain operations and I have a base class like this:
abstract class Command[A, B <: BaseModel, T[X] <: CommandResponseWrapper[X] forSome { type X }](repository: BaseRepository[A, B], entity: B) {
@throws(classOf[Exception])
def execute: Future[T[X] forSome { type X }]
}
Now, take this concrete command as a sample of the issues I'm having:
case class AgentExecutionListCommand(repository: AgentExecutionRepository[Int, AgentExecution], entity: AgentExecution)(implicit ec: ExecutionContext) extends Command[Int, AgentExecution, AgentExecutionListResponse[Seq[AgentExecution]]](repository, entity){
override def execute: Future[AgentExecutionListResponse[Seq[AgentExecution]]] = {
repository.getAllMastersForAgent(entity.agentId).map(ae => AgentExecutionListResponse(ae))
}
override def toString: String = "Command is: AgentExecutionListCommand"
}
case class AgentExecutionListResponse[Seq[AgentExecution]](response: Seq[AgentExecution]) extends CommandResponseWrapper
The method getAllMastersForAgent in the repository, returns a Future[Seq[AgentExecution]], but the compiler shows an error in this line:
repository.getAllMastersForAgent(entity.agentId).map(ae => AgentExecutionListResponse(ae))
The error is: Expression of type AgentExecutionListResponse[Seq] doesn't conform to expected type S_
What does that mean?
Another error is:
Error:(11, 189) org.jc.dpwmanager.commands.AgentExecutionListResponse[Seq[org.jc.dpwmanager.models.AgentExecution]] takes no type parameters, expected: one
case class AgentExecutionListCommand(repository: AgentExecutionRepository[Int, AgentExecution], entity: AgentExecution)(implicit ec: ExecutionContext) extends Command[Int, AgentExecution, AgentExecutionListResponse[Seq]](repository, entity){
Why does it say that it takes no type parameters and then again, expects one. I don't get it. Please help!
Thanks in advance!
The problem is here:
case class AgentExecutionListResponse[Seq[AgentExecution]](response: Seq[AgentExecution]) extends CommandResponseWrapper
The [...]
thingy should be after CommandResponseWrapper
not after the class name
case class AgentExecutionListResponse(
response: Seq[AgentExecution]
) extends CommandResponseWrapper[Seq[AgentExecution]]
For the second error:
T[X] <: CommandResponseWrapper[X] forSome { type X }
means you told the compiler T
has to be a type constructor with a single parameter (that's why you can write T[X]
in execute
's signature), but AgentExecutionListResponse[Seq[AgentExecution]]
doesn't take parameters (you can't write AgentExecutionListResponse[Seq[AgentExecution]][SomeType]
). So you can't use it as T
. Just as if you try to call foo()
where foo
has a parameter.
Also, I think that the scope of X
in forSome
is just CommandResponseWrapper[X] forSome { type X }
, so it's the same as T[X] <: CommandResponseWrapper[_]
. So naming X
in T[X]
is confusing.
Given the signature you expect for AgentExecutionListCommand#execute
, the fix might be just
abstract class Command[A, B <: BaseModel, T <: CommandResponseWrapper[_]](repository: BaseRepository[A, B], entity: B) {
@throws(classOf[Exception])
def execute: Future[T]
}
but it really depends on what you want.
For the first, it isn't clear where S_
comes from: perhaps from getAllMastersForAgent
's signature? In that case it would be necessary for the answer. But the second is a more fundamental issue.
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.