0

我正在Coursera 上学习Scala 中的函数式编程原理课程。有一个Peano 数字的实现示例,如下所示:

abstract class Nat {
  def isZero: Boolean
  def predecessor: Nat
  def successor: Nat = new Succ(this)
  def +(that: Nat): Nat
  def -(that: Nat): Nat
}

object Zero extends Nat {
  def isZero = true
  def predecessor: Nat = throw new Error("0.predecessor")
  def +(that: Nat): Nat = that
  def -(that: Nat): Nat = if (that.isZero) this else throw new Error("negative number")
}

class Succ(n: Nat) extends Nat {
  def isZero: Boolean = false
  def predecessor: Nat = n
  def +(that: Nat): Nat = new Succ(n + that)
  def -(that: Nat): Nat = if (that.isZero) this else n - that.predecessor
}

我写了几个单元测试。大多数通行证,但以下通行证 - 以天真的方式编写 - 因明显原因而失败(不同实例的比较):

trait Fixture {
  val one = new Succ(Zero)
  val two = new Succ(one)
}

test("successor of zero is one") {
  new Fixture {
    assert(Zero.successor == one)
  }
}

test("successor of one is two") {
  new Fixture {
    assert(one.successor == two)
  }
}

test("one plus zero is one") {
  new Fixture {
    assert((one + Zero) === one)
  }
}

test("one plus one is two") {
  new Fixture {
    assert((one + one) === two)
  }
}

我的问题是:应该如何实施单元测试来成功测试 peano 数字的 + 和 - 操作?

以防万一,在这里您可以找到剩余的单元测试

4

2 回答 2

1

感谢Cyrille Corpet的提示,在我看来,使用case class按结构比较,而不是按引用比较”很优雅。现在所有单元测试都通过了,没有任何变化。

case class Succ(n: Nat) extends Nat {
  def isZero: Boolean = false
  def predecessor: Nat = n
  def +(that: Nat): Nat = new Succ(n + that)
  def -(that: Nat): Nat = if (that.isZero) this else n - that.predecessor
}
于 2017-05-15T13:23:53.463 回答
-1

查看您的测试,您似乎想要测试相等条件,您应该为此编写一个函数:

def eq(i: Nat, j: Nat): Boolean =
  if (i.isZero | j.isZero)
    i.isZero == j.isZero
  else
    eq(i.predecessor, j.predecessor)

通过调用替换你的===& 。您也可以考虑覆盖 equal 方法,而不是将其作为外部(测试)函数。==eq

于 2017-05-15T13:07:26.377 回答