Scala:返回依赖类型

问题描述 投票:1回答:1

在我的应用程序中,我有一组闭合的操作,返回相应的设置响应,如下所示。

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)
}

至于我对类型成员和类型投影的理解,我可以做到以下几点。根据scala编译器,它们是完全有效的语句

val esr:StartExecutionOperation#R = ExecutionStartedResponse(1)
val teo:TerminateExecutionOperation#R = ExecutionTerminatedResponse(-1)
val ruo:RecordUpdateOperation#R = UpdateRecordedResponse(0)

但是,我现在想在函数中使用它们;这通常更有用。现在,我如何将输出类型指定为依赖类型?

def updateState[O <: Operation](operation: O) = operation match {
    case StartExecutionOperation() =>  ExecutionStartedResponse(1)
    case TerminateExecutionOperation() => ExecutionTerminatedResponse(-1)
    case RecordUpdateOperation() => UpdateRecordedResponse(0)
}

更具体地说,我不希望在我的情况下函数的返回类型是OperationCompletionResponse,但类似于Operation#R或operation.R

我怎么能做到这一点?

scala dependent-type path-dependent-type type-projection
1个回答
2
投票

updateState的路径依赖类型将与operation的类型直接相关。你不想在体内匹配operation,因为这永远不会给你你正在寻找的类型R

你定义了一个操作,它给你这个R和那个createResponse。因为createResponse期望一个整数参数,你必须以某种方式在updateState中给它。看来你的每个操作都有一些默认状态,所以你可以定义def defaultState: Int Operation然后有

def updateState(op: Operation): op.R = op.createResponse(op.defaultState)` 

如果这不能回答您的问题,请对其进行编辑,以便更具体地了解您要在此状态下尝试实现的目标。

© www.soinside.com 2019 - 2024. All rights reserved.