scala - 何时对递归函数/方法使用辅助递归函数/方法
问题描述
在函数式编程课程的工作表中,我被要求用 Scala 编写一个函数(尽管我认为教授可能指的是方法),该函数递归地在新行的列表中打印元素,并带有行号,结果如下:
scala> printCounter (List ("the", "rain", "in", "spain"))
[001] the
[002] rain
[003] in
[004] spain
工作表上提供的解决方案如下所示:
def printCounterAux [X] (xs:List[X], count:Int) : Unit = {
xs match {
case Nil => ()
case y::ys => {
println ("[%03d] %s".format (count, y))
printCounterAux (ys, count + 1)
}
}
}
def printCounter [X] (xs:List[X]) : Unit = {
printCounterAux (xs, 1)
}
printCounter (List ("the", "rain", "in", "spain"))
我没有想到要创建一个辅助方法。作为仍在处理递归的人,我的问题是:您如何知道何时需要创建辅助递归方法?在这种情况下,信号会是多个参数吗?还是仅仅是大量接触这些方法的问题?非常感谢您可以分享的任何建议。干杯。
解决方案
printCounterAux
具有不同于printCounter
. 不仅如此,API 的变化与方法的功能无关,纯粹是一个实现细节。(例如,已经printCounter
用循环实现了,就没有必要了。)
因此,您希望对消费者隐藏此 API。
然而,为了真正正确地隐藏此 API,printCounterAux
应该是 的内部函数,printCounter
如下所示:
def printCounter[X](xs: List[X]): Unit = {
printCounterAux()
def printCounterAux[X](xs: List[X] = xs, count: Int = 1): Unit = xs match {
case Nil => ()
case y :: ys => {
println("[%03d] %s".format(count, y))
printCounterAux(ys, count + 1)
}
}
}
printCounter(List("the", "rain", "in", "spain"))
请注意,在许多情况下,您需要随身携带某种“状态”,而在纯函数式语言的递归函数中,携带该状态的一个非常方便的地方是函数的参数。因此,您通常必须修改参数列表以添加状态参数(如count
本例所示),该参数不应暴露给消费者。
推荐阅读
- javascript - 如何从节点js服务器文件传递变量
- flutter - 为什么该列占其父级(容器)的全宽
- python - 回归两个多维数据集?
- encryption - PgP加密和解密使用BouncyCastle c#在数据中带有双引号
- html - 社交媒体的超链接在contact.html中不起作用
- c - 连接两个字符串但为空。请告诉我这个错误
- ios - iOS - Swift - UICollectionView 和 ScrollToItemAtIndexPath 的辅助功能 VoiceOver 问题
- bash - 不包括第一个元素的 Bash 脚本
- laravel - 在 Laravel 中评估环境变量
- python - 我无法解密文件