将foreach转换为包含forall匹配器

时间:2015-08-17 01:01:51

标签: scala specs2

我在规范中有以下表达式,目的是确保每个元素的值distanceToEnd非常接近其后面元素的distanceFromPrevious值的总和。 / p>

foo.tails.foreach {
  case h +: t => h.distanceToEnd.miles must
    beCloseTo(t.map(_.distanceFromPrevious.miles).sum, 10e-10)
  case _ => ok
}

理想情况下,这应采用foo.tails must contain { ... }.forall格式,但我无法理解如何为ValueCheck创建必要的contains参数。我如何转换这个特定的例子?

2 个答案:

答案 0 :(得分:1)

不幸的是,类型推断不适用于部分函数,​​因此您需要明确匹配:

 foo.tails must contain { ts: List[Foo] =>
   ts match {
     case h +: t => h.distanceToEnd.miles must
       beCloseTo(t.map(_.distanceFromPrevious.miles).sum, 10e-10)
     case _ => ok
   }
}.forall

答案 1 :(得分:0)

如果您在使用任何specs2匹配器之前计算forall的部分总和并减去distanceFromPrevious,则可以使用distanceToEnd。然后你可以使用beCloseTo matchers中的一个与0进行比较,如下所示:

foo.tail.scanRight(0.0)(_.distanceFromPrevious.miles + _).init  // calculate partial sums of previous distances
    .zip(foo.init.map(_.distanceToEnd.miles))                   // combine with end distances
    .map(t => t._1 - t._2)                                      // take difference of summed and end distances
    .must(contain(be ~(0.0 +/- 10e-10)).forall)                 // all differences should be effectively 0