如何改进这个递归函数?

How can this recursive function be improved?

walkTree 中的代码遍历 fileTree 节点列表中表示的文件树。它做我想做的,即递归打印树中的每个条目。但我觉得它可以改进很多。我还认为我在破坏尾递归 运行 2 `visit statements at the end of the patern matching.

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

执行此操作的更好方法是什么?

至少,我会分开 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