我正在 Scala 中为大学的实验室实现符号分析。
为此,我需要对抽象值进行算术运算,例如 Pos
, Neg
, Zero
,NonPos
, NonNeg
, ... 所以我必须声明方法 +
, -
, *
, /
等等……
那些抽象的值(value)观。我实际上不需要定义一切
成对,但可以在 Pos
上定义操作的“核心” , Neg
, 和 Zero
,
然后使用上限来定义,例如:
NonPos + Pos = leastUpperBound(Zero + Pos, Neg + Pos)
例如
leastUpperBound(Zero, Neg) = NonPos
在 Scala 中,我使用 case 对象来表示值,并有一个
leastUpperBound()
每个人的方法。但我还有一些代码重复我无法摆脱,例如我定义:
case object NonNeg extends Sign {
def +(other: Sign) = leastUpperBound(Zero + other, Pos + other)
def -(other: Sign) = ...
def * = ...
...
}
而我必须为:
case object NonPos extends Sign {
def +(other: Sign) = leastUpperBound(Zero + other, Neg + other)
...
}
然后再次:
case object NonZero extends Sign {
def +(other: Sign) = leastUpperBound(Neg + other, Neg + other)
...
}
我想知道是否有可能拥有某种“类型工厂”,以便我可以
本着以下精神说点什么:
case object NonNeg extends UpperBoundSign[Pos, Zero]
我的直觉是
Pos
是不可能的和 Zero
正在 object
,但我对 Scala 不太熟悉,所以我可能会忘记一些功能或模式
请允许我这样做。
有没有人有删除这种重复的想法?
也许 2.10 中的 Scala 宏很适合解决这个问题?
我希望问题很清楚,
谢谢你。
编辑:感谢@cmbaxter 的回答和我的一些重构,我想出了一个我喜欢的解决方案。如果有人有兴趣看到它,可以在那里找到:https://gist.github.com/Ricordel/5553405 .
最佳答案
我认为您可能会混淆类型标识符和类的实例。我相信为了获得您想要的功能,您需要定义 UpperBoundSign
作为具有两个构造函数参数的抽象类,而不是具有两个类型标识符插槽的泛型类型。这是一个过于简化的解决方案选项,可以满足您的需求。如果这完全不是您想要的,我深表歉意:
trait Sign{
def +(other: Sign):Sign
}
abstract class UpperBoundSign(pos:Sign, neg:Sign) extends Sign{
def leastUpperBound(pos:Sign, neg:Sign):Sign
def +(other: Sign) = leastUpperBound(pos + other, neg + other)
}
case object Pos extends Sign{
def +(other:Sign) = ...
}
case object Neg extends Sign{
def +(other:Sign) = ...
}
case object NonNeg extends UpperBoundSign(Pos, Neg){
def leastUpperBound(pos:Sign, neg:Sign) = ...
}
关于scala - 在 Scala 中将一个对象定义为对另外两个对象的操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16459429/