scala - 在 Scala 中将一个对象定义为对另外两个对象的操作

标签 scala

我正在 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/

相关文章:

scala - 使用 Scala 2.10 进行枚举和映射

validation - 如何在Scala中实现简单的验证

scala - 挑选列表列表的第 N 个元素并将该值作为值列表返回

scala - Mixin 来包装 Scala 特征的每个方法

Scala LinkedHashMap.toMap 保留顺序?

scala - 逆变和 val

scala - 如何定义不可变的 Set 比较方法将使用的自定义相等操作

scala - 运行 sbt 结果为 "com.typesafe.sbteclipse#sbteclipse;1.4.0: not found"

java - 无法应用插件[class 'org.gradle.api.plugins.scala.ScalaBasePlugin']:Gradle v2.13

scala - 避免名称与 Cake Pattern 冲突