转换为尾递归

嘿,我试图让函数式编程(尤其是使用F#)变得更加舒适,并且当涉及到构建尾递归函数时,我碰到了一堵墙。 我非常喜欢将基本递归(其中函数基本上每次调用时自动调用一次)转换为尾递归,但现在我的情况稍微复杂一些。

在我的情况下,函数必须接受一个列表作为参数。 当函数被调用时,我必须从列表中删除第一个元素,然后使用列表的其余部分重复。 然后我需要将我以某种方式删除的第一个元素应用于递归结果。 接下来,我删除第二个元素并执行相同的操作(注意:当我说“删除seond元素”时,即从原始列表中删除,所以在递归中传递的列表也包含第一个元素)。 我也为列表中的第三,第四等元素做同样的事情。

有没有办法将上述情况转换为尾递归函数? 也许嵌套的尾递归函数? 谢谢你的回答。


好的,这是我的基本代码。 这个特定的一个是置换生成器(我不太关心置换部分,但是 - 这是我想关注的递归):

let permutationsOther str =
  match str with
  | value :: [] ->
    [[value]]
  | _ ->
    let list = (List.map (fun a -> // This applies the remove part for every element a
      let lst = (List.filter (fun b -> b <> a) str) // This part removes element a from the list
      let permutedLst = permutations lst // recursive call
      consToAll a permutedLst // constToAll this is my own function which performs "cons" operation with a and every element in the list permutedLst
    ) str)
    List.reduce (fun acc elem -> elem @ acc) list // flatten list of lists produce by map into a single list

我希望这很清楚 - 如果需要,我会很乐意提供澄清。

顺便说一句,我找到了一种方法来重写这个特定的函数,以便它只使用一个递归,但这不仅仅是一个明智的决定。 然而,这鼓励了我,可能有一种将多次递归转换为单次递归的一般方法,但我还没有找到它。


转换为CPS应该做到这一点:

注1:样本的来源直接在浏览器中输入,因此可能包含错误:(但我希望它能显示出总体思路。

注2:consToAll函数也应该转换为CPS:consToAll:'T - >'T list list - >('T list list - >'R) - >'R

let remove x l = List.filter ((<>) x) l // from original post: should duplicates also be removed ???

let permute l =
    let rec loop k l = 
        match l with
        | [] -> k []
        | [value] -> k [[value]]
        | _ -> filter l [] l (fun r -> r |> List.reduce (fun acc elem -> elem @ acc) |> k )
    and filter l acc orig fk = 
        match l with
        | [] -> fk acc
        | x::xs ->
            remove x orig 
                |> loop (fun res ->
                    consToAll x res (fun rs -> filter xs (rs::acc) orig fk)                    
                    )
    loop id l
链接地址: http://www.djcxy.com/p/80567.html

上一篇: Conversion to tail recursion

下一篇: How do I break out of a loop in Scala?