In my application, I have a closed set of operations that return a corresponding set responses as shown below.
sealed trait OperationCompletionResponse {
val state: Int
}
case class ExecutionStartedResponse(state: Int) extends OperationCompletionResponse
case class UpdateRecordedResponse(state: Int) extends OperationCompletionResponse
case class ExecutionTerminatedResponse(state: Int) extends OperationCompletionResponse
sealed trait Operation {
type R
def createResponse(state: Int): R
}
case class StartExecutionOperation() extends Operation {
type R = ExecutionStartedResponse
override def createResponse(state: Int): ExecutionStartedResponse = ExecutionStartedResponse(state)
}
case class RecordUpdateOperation() extends Operation {
type R = UpdateRecordedResponse
override def createResponse(state: Int): UpdateRecordedResponse = UpdateRecordedResponse(state)
}
case class TerminateExecutionOperation() extends Operation {
type R = ExecutionTerminatedResponse
override def createResponse(state: Int): ExecutionTerminatedResponse = ExecutionTerminatedResponse(state)
}
As far as my understanding of type members and type projection go, I can do the following. They're perfectly valid statements according to scala compiler
val esr:StartExecutionOperation#R = ExecutionStartedResponse(1)
val teo:TerminateExecutionOperation#R = ExecutionTerminatedResponse(-1)
val ruo:RecordUpdateOperation#R = UpdateRecordedResponse(0)
However, I would now like to use them in a function; which is often more useful. Now, how would I specify the output type as a dependent type?
def updateState[O <: Operation](operation: O) = operation match {
case StartExecutionOperation() => ExecutionStartedResponse(1)
case TerminateExecutionOperation() => ExecutionTerminatedResponse(-1)
case RecordUpdateOperation() => UpdateRecordedResponse(0)
}
More specifically, I do not want the return type of the function in my case to be OperationCompletionResponse but something like Operation#R or operation.R
How can I accomplish that?