'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的类型推断可以“通过” implicit
和unapply
,它可能会猜测precision
和{{ 1}}的类型只能为recall
。
我目前遇到的问题是Double
的返回类型为fold
。这有点令人失望,我想避免不得不写一个明确的Any
。有什么方法可以实现?
答案 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
而不是fold
。 fold
是foldLeft
的一种特殊情况,其中种子类型与列表的元素类型相同。在这种情况下,折叠是可以的,因为种子和元素都为Double,但是我个人更喜欢始终使用foldLeft(或在需要时使用foldRight)。我相信,在这种情况下,更改为foldLeft可能会解决您的类型推断问题。
curve.getPoints.foldLeft(0.0) {
case (maxRecall, Point(precision, recall)) =>
if (recall > maxRecall && precision >= precisionFloor)
recall
else
maxRecall
}