Если вы не хотите изменять сигнатуру, вам придется использовать локальную функцию и сделать эту функцию хвостовой рекурсивной
def standardDeviation[T](elements: List[T], property: T => Double): Double = {
val values = elements.map(property)
val size = elements.size.toDouble
// this could acually be replaced by values.sum
@scala.annotation.tailrec
def calculateSum(remaining: List[Double], acc: Double): Double = remaining match {
case head :: tail => calculateSum(tail, acc + head)
case Nil => acc
}
val mean = calculateSum(values, 0.0) / size
@scala.annotation.tailrec
def calculateSumOfDiffs(remaining: List[Double], acc: Double): Double = remaining match {
case head :: tail => calculateSumOfDiffs(tail, acc + Math.pow(head - mean, 2.0))
case Nil => acc
}
Math.sqrt(calculateSumOfDiffs(values, 0.0) / (size - 1))
}
Когда вы выполняете хвостовую рекурсивную обработку, вы должны каким-то образом передавать результаты: до сих пор, так что если вы не можете представить промежуточные результаты в API, это единственный способ.
Однако вам не нужно реализовывать это с помощью tail re c, а вместо этого использовать некоторый функциональный подход вместо:
def standardDeviation[T](elements: List[T], property: T => Double): Double = {
val values = elements.map(property)
val size = values.size.toDouble
val mean = values.sum / size
Math.sqrt(values.map(x => Math.pow(x - mean, 2.0)).sum / (size - 1))
}