私はスカラを教えていて、自分のFPスキルを肥えています。スカラのネストされたリストを再帰的に処理する
プログラミング言語の基礎(available here)の参考文献の1つに、簡単な再帰関数の便利なリストがあります。ページ27/50のページでは、swapper()関数を実装するように求められています。 Scalaで
(swapper s1 s2 slist) returns a list the same as slist, but
with all occurrences of s1 replaced by s2 and all occurrences of s2 replaced by s1.
> (swapper ’a ’d ’(a b c d))
(d b c a)
> (swapper ’a ’d ’(a d() c d))
(d a() c a)
> (swapper ’x ’y ’((x) y (z (x))))
((y) x (z (y)))
、これは次のようになります。
swapper("a", "d", List("a","b","c","d"))
swapper("a", "d", List("a","d",List(),"c","d"))
swapper("x", "y", List(List("x"), "y", List("z", List("x"))))
マイScalaのバージョンでは、すべてのバージョンが最終的なXを保存処理します。
def swapper(a: Any, b: Any, lst: List[Any]): List[Any] ={
def r(subList :List[Any], acc : List[Any]): List[Any] ={
def swap (x :Any, xs: List[Any]) =
if(x == a){
r(xs, acc :+ b)
} else if (x == b) {
r(xs, acc :+ a)
} else {
r(xs, acc :+ x)
}
subList match {
case Nil =>
acc
case List(x) :: xs =>
r(xs, r(List(x), List()) +: acc)
case x :: xs =>
swap(x,xs)
//case List(x) :: xs =>
}
}
r(lst, List())
}
本能的に、私は「XS ::ケース一覧(x)は、」私はセクションにはスワップを持っていないので、これがあると思いますが、私はまだそれを修正するために苦労しています。
さらに難しく、この場合でもテールコールの最適化は中断されます。私はこれをどうやって行うことができますか?一般的な解決法についてもっと知るためにどこに行くことができますか?
かさえsimplier(@marcospereiraのおかげで)::
def swapper(a:Any, b:Any, list:List[Any]):List[Any] =
list.map {
case item if item==a => b
case item if item==b => a
case item:List[Any] => swapper(a, b, item)
case item => item
}
OK!あなたの洞察をお寄せいただきありがとうございます。 @tailrecアノテーションを追加すると、再帰呼び出しは文句を言いませんが、末尾の位置ではありません。 – peoplemerge