类型推断并且不适用

时间:2018-09-25 19:56:25

标签: scala

's我正在使用implicits来包装需要使用的现有库,并且我正在尝试使用unapply来实现一种不错的语法。

Point是一个遗留Java类,我使用unapply方法创建了这个隐式包装:

 implicit class WrappedPoint(point: Point) {
   def unapply(point: Point): (Double, Double) = 
    (point.getX.asInstanceOf[Double], point.getY.asInstanceOf[Double])
   }

使用unapply的原因是我希望能够这样写:

curve.getPoints.fold(0.0) {
  case (maxRecall: Double, (precision: Double, recall: Double)) =>
    if (recall > maxRecall && precision >= precisionFloor)
      recall
    else
      maxRecall
}

理想情况下,甚至没有Double提到:如果Scala的类型推断可以“通过” implicitunapply,它可能会猜测precision和{{ 1}}的类型只能为recall

我目前遇到的问题是Double的返回类型为fold。这有点令人失望,我想避免不得不写一个明确的Any。有什么方法可以实现?

1 个答案:

答案 0 :(得分:1)

您可以创建Point对象随播广告,并在其中实现unapply

此外,您未应用的签名是错误的,您需要返回touple的Option,而不仅是touple:

object Point(point: Point) {
    def unapply(point: Point): Option[(Double, Double)] = 
     Some((point.getX.asInstanceOf[Double], point.getY.asInstanceOf[Double]))
}

此外,我总是建议使用foldLeft而不是foldfoldfoldLeft的一种特殊情况,其中种子类型与列表的元素类型相同。在这种情况下,折叠是可以的,因为种子和元素都为Double,但是我个人更喜欢始终使用foldLeft(或在需要时使用foldRight)。我相信,在这种情况下,更改为foldLeft可能会解决您的类型推断问题。

curve.getPoints.foldLeft(0.0) {
  case (maxRecall, Point(precision, recall)) =>
    if (recall > maxRecall && precision >= precisionFloor)
      recall
    else
      maxRecall
 }