【发布时间】:2021-08-25 17:35:55
【问题描述】:
我必须开发类 StackMachine[T]。如果 T = Boolean,那么应该有逻辑运算。如果 T = Int,Double,Long 等,应该有算术运算。首先我开发了 Stack[T] 类。
class Stack[T](val stack: List[T]) {
val length: Int = stack.length
def isEmpty: Boolean = {length == 0}
def push(x: T): Stack[T] = {
new Stack[T](x :: stack)
}
def peak: T = {
if (this.isEmpty)
throw new ArrayIndexOutOfBoundsException
else stack.head
}
def pop(): Stack[T] = {
if (this.isEmpty)
throw new ArrayStoreException()
val x :: xs = stack
new Stack[T](xs)
}
薄是我不知道如何开发 StackMachine[T] 取决于类型的操作的存在。 我试过这个:
case class StackMachine[T](val stack:Stack[T]){
def const(x: T): StackMachine[T] = {new StackMachine[T](new Stack[T](this.stack.push(x).stack))}
def dup: StackMachine[T] = {new StackMachine[T](new Stack[T](this.stack.push(this.stack.peak).stack))}
def swap: StackMachine[T] = {
val startStack = this.stack
val startPeak = startStack.peak
val secondStack = startStack.pop()
val secondPeak = secondStack.peak
val finalStack = secondStack.pop().push(startPeak)
StackMachine[T](stack)
}
def and(): StackMachine[Boolean] = {
val startStack = this.stack.asInstanceOf[Stack[Boolean]]
val startPeak = startStack.peak
val secondStack = startStack.pop()
val secondPeak = secondStack.peak
StackMachine[Boolean](new Stack[Boolean](secondStack.push(startPeak && secondPeak).stack))
}
def or: StackMachine[Boolean] = {
val startStack = this.stack.asInstanceOf[Stack[Boolean]]
val startPeak = startStack.peak
val secondStack = startStack.pop()
val secondPeak = secondStack.pop().peak
StackMachine[Boolean](new Stack[Boolean](secondStack.push(startPeak || secondPeak).stack))
}
def xor: StackMachine[Boolean] = {
val startStack = this.stack.asInstanceOf[Stack[Boolean]]
val startPeak = startStack.peak
val secondStack = startStack.pop()
val secondPeak = secondStack.pop().peak
StackMachine[Boolean](new Stack[Boolean](secondStack.push(startPeak ^ secondPeak).stack))
}
def sum(input : T)(implicit N: Numeric[T]) = {
val startStack = this.stack
val startPeak = startStack.peak
val secondStack = startStack.pop()
StackMachine[T](new Stack[T](secondStack.push(N.plus(startPeak,input)).stack))
}
def dif(input : T)(implicit N: Numeric[T]) = {
val startStack = this.stack
val startPeak = startStack.peak
val secondStack = startStack.pop()
StackMachine[T](new Stack[T](secondStack.push(N.minus(startPeak,input)).stack))
}
def mul(input : T)(implicit N: Numeric[T]) = {
val startStack = this.stack
val startPeak = startStack.peak
val secondStack = startStack.pop()
StackMachine[T](new Stack[T](secondStack.push(N.toDouble(startPeak).*(N.toDouble(input)).asInstanceOf[T]).stack))
}
def div(input : T)(implicit N: Numeric[T]) = {
val startStack = this.stack
val startPeak = startStack.peak
val secondStack = startStack.pop()
StackMachine[T](new Stack[T](secondStack.push(N.toDouble(startPeak)./(N.toDouble(input)).asInstanceOf[T]).stack))
}
def min(input : T)(implicit N: Numeric[T]) = {
val startStack = this.stack
val startPeak = startStack.peak
val secondStack = startStack.pop()
StackMachine[T](new Stack[T](secondStack.push(N.min(startPeak,input)).stack))
}
def max(input : T)(implicit N: Numeric[T]) = {
val startStack = this.stack
val startPeak = startStack.peak
val secondStack = startStack.pop()
StackMachine[T](new Stack[T](secondStack.push(N.max(startPeak,input)).stack))
}
}
但这是错误的,因为操作不应该有输入参数,因为所有变量都必须从堆栈中获取。不仅如此,这样我就无法创建 diff 和 mul 函数。 我想使 StackMachine[T] 抽象并使用隐式对象,但失败了,因为在这种情况下,我的函数不能返回 StackMachine。可能是我对隐式理解不够好还是有另一种方法?
【问题讨论】:
-
您可以使用
def and()(implicit ev: T <:< Boolean): StackMachine[Boolean],对于数字运算,您可以查看Numeirc typeclass - Thought。说实话。我想我会做的是为不同的机器设置不同的类。 -
我也会这样做,但这是任务。说实话,我不明白这种结构有什么帮助,因为 ev 没有布尔运算
-
ev暗示T是 Boolean 因此,您应该能够将 T 用作 Boolean 在该方法的主体中。但是,如果这是预期的解决方案,您应该已经知道了。 - 你能分享一下你的任务的字面意思吗? (也许你不能因为抄袭)。如果我们能知道您应该在此处使用哪个主题/技术(如果这是家庭作业) 或者您要解决的元问题是什么(如果这是工作). -
好的,但是我有一个类型不匹配,因为在
StackMachine[Boolean](new Stack[Boolean](secondStack.push(startPeak && secondPeak).stack))secondStack.push 需要 T 但找到布尔值。 -
任务正文:在实验室工作过程中,需要开发一个广义类(类变体见附表)。该任务的一个特殊特征是对正在开发的类的对象的某些操作的含义取决于该类被参数化的类型。此外,即使某些操作的存在也可能取决于典型参数。此功能是使用隐式对象和隐式方法参数实现的。