我是 Scala 的新手,我正在尝试使用类型边界来避免以下代码中的代码重复(从不相关的东西中清除):
trait StandardStep1[-I1] {
def next_step(i:I1):StandardStep2
}
trait StandardStep2
trait UniqueStep1[-I1] extends StandardStep1[I1] {
def next_step(i:I1):UniqueStep2
}
trait UniqueStep2 extends StandardStep2
class DoubleStandardStep1[-IL,-IR](left:StandardStep1[IL], right:StandardStep1[IR]) extends StandardStep1[(IL,IR)] {
def next_step(i:(IL,IR)) = {
val (i_left, i_right) = i
val new_left = left.next_step(i_left)
val new_right = right.next_step(i_right)
new DoubleStandardStep2(new_left, new_right)
}
}
class DoubleStandardStep2(left:StandardStep2, right:StandardStep2) extends StandardStep2
class DoubleUniqueStep1[-IL,-IR](left:UniqueStep1[IL], right:UniqueStep1[IR]) extends UniqueStep1[(IL,IR)] {
def next_step(i:(IL,IR)) = {
val (i_left, i_right) = i
val new_left = left.next_step(i_left)
val new_right = right.next_step(i_right)
new DoubleUniqueStep2(new_left, new_right)
}
}
class DoubleUniqueStep2(left:UniqueStep2, right:UniqueStep2) extends UniqueStep2
解释:
StandardStep1
表示某个状态机中的一个步骤,并且有一个针对给定输入next_step
给出 a 的操作。StandardStep2
UniqueStep1
是一种特殊类型,当它被调用时会StandardStep1
给出一个- 显然必须从中继承。UniqueStep2
next_step
UniqueStep2
StandardStep2
现在我必须编写一个DoubleStep包装器:DoubleStandardStep1
包装太StandardStep1
s,并在调用DoubleStandardStep2
它时返回 a next_step
。
DoubleUniqueStep1
做同样的事情,但它返回一个DoubleUniqueStep2
.
*DoubleStep*s' 的实现next_step
有一个明显的代码重复:它们都将输入拆分为i_left
并以相同的方式i_right
调用它们的包装步骤。next_step
我想知道如何通过创建一个通用抽象DoubleStep1来完成这部分代码,从而消除这种代码重复:
object DoubleStepHelper {
def next_step_args[IL,IR,SL <: StandardStep1[IL],SR <: StandardStep1[IR]](left:SL,right:SR)(i:(IL,IR)) = {
val (i_left, i_right) = i
val new_left = left.next_step(i_left)
val new_right = right.next_step(i_right)
(new_left, new_right)
}
}
class DoubleStandardStep1[-IL,-IR](left:StandardStep1[IL], right:StandardStep1[IR]) extends StandardStep1[(IL,IR)] {
def next_step(i:(IL,IR)) = {
((l,r) => new DoubleStandardStep2(l,r)).tupled(DoubleStepHelper.next_step_args(left,right)(i))
}
}
class DoubleStandardStep2(left:StandardStep2, right:StandardStep2) extends StandardStep2
class DoubleUniqueStep1[-IL,-IR](left:UniqueStep1[IL], right:UniqueStep1[IR]) extends UniqueStep1[(IL,IR)] {
def next_step(i:(IL,IR)) = {
((l,r) => new DoubleUniqueStep2(l,r)).tupled(DoubleStepHelper.next_step_args(left,right)(i))
}
}
class DoubleUniqueStep2(left:UniqueStep2, right:UniqueStep2) extends UniqueStep2
尝试编译此代码(scala 2.9.2)失败并显示以下消息:
类型不匹配; 找到:(this.StandardStep2,this.StandardStep2) 必需:(this.UniqueStep2,this.UniqueStep2) ((l,r) => new DoubleUniqueStep2(l,r)).tupled(DoubleStepHelper.next_step_args(left,right)(i)) ^
我假设发生这种情况是因为DoubleStepHelper.next_step_args
假设返回一个(StandardStep2, StandardStep2)
值,当我们想用DoubleUniqueStep2
.
你能想出解决这个问题的方法吗?如何告诉编译器DoubleStepHelper
next_step_args 可能返回一个(UniqueStep2, UniqueStep2)
ifSL
并SR
继承自UniqueStep1
?
一个不错的功能可能是能够将结果类型定义为(SL.next_step, SR.next_step)next_step_args
之类的东西,这意味着它的返回类型是根据 和 中特定函数 ( next_step )的返回类型构建的。SL
SR
“视图”边界可以以任何方式解决它吗?
我可以使用asInstanceOf强制转换,但这看起来很难看。
谢谢