如何改进这种递归函数?

时间:2015-04-15 08:52:09

标签: recursion pattern-matching ocaml

walkTree中的代码遍历fileTree个节点列表中表示的文件树。它做我想要的,即以递归方式打印树中的每个条目。但我觉得它可以大大改善。我也认为我通过在patern匹配结束时运行2个访问语句来破坏尾递归。

type 'a fileTree =
  | File of 'a
  | Folder of 'a * ('a fileTree list)

let fileTreeStructure = [
  File "file1.txt" ;
  Folder ("testFolder1", [Folder ("nestedFolder1", [])]) ;
  File "test1.txt";
  Folder ("testFolder2", [Folder ("nestedFolder2", [])]) ;
  File "test2.txt";
]

let walkTree tree =
  let rec visit = function
    | [] -> print_string "\n"
    | File f :: t ->
      Printf.printf "file: %s\n" f ;
      visit t
    | Folder (name, contents) :: t ->
      Printf.printf "name: %s\n" name ;
      visit contents ;
      visit t in
  visit tree;;

walkTree fileTreeStructure

最好的办法是什么?

1 个答案:

答案 0 :(得分:3)

至少,我要将listfileTree分开:

let walkTree tree =
  let rec visit = function
    | File f -> Printf.printf "file: %s\n" f
    | Folder (name, contents) ->
        Printf.printf "name: %s\n" name;
        List.iter visit contents
  in visit tree

let _ = List.iter walkTree fileTreeStructure

修改(使用 @nlucaroni 建议;我还替换了List.iter功能以进行说明):

如果您希望walkTree函数按字面string fileTree list(而不是第一个示例中的string fileTree)接受:

let walkTree tree =
  let rec iter = function
    | [] -> ()
    | a::l -> visit a; iter l
  and visit = function
    | File f -> Printf.printf "file: %s\n" f
    | Folder (name, contents) ->
        Printf.printf "name: %s\n" name;
        iter contents
  in iter tree