>我正在尝试递归浏览文件和文件夹的嵌套列表。当我这样做时,我想打印我访问的文件和文件夹的名称,但我做错了什么。这是我所拥有的:
type 'a fileTree =¬
| File of 'a¬
| Folder of 'a * ('a fileTree list)
let printFiles tree =
let rec visit tree = function
| [] -> print_string "Done"
| File f :: t -> visit t
| Folder (name, contents) :: t -> visit contents
in
visit tree
这样做我得到
Error: This expression has type 'a fileTree list -> unit but an expression was expected of type unit
对于第 (File f :: t -> visit t)
行。
我做错了什么?
编辑 1
代码现在是
let printFiles tree =
let rec visit = function
| File file -> Printf.printf "file: %sn" file
| Folder (name, contents) ->
Printf.printf "folder: %sn" name;
List.iter visit contents
in
List.iter visit tree
但是我仍然在最后一行收到此错误:
Error: This function has type ('a -> unit) -> 'a list -> unit
It is applied to too many arguments; maybe you forgot a `;'
你忘记了这里的括号:
print_string "File " ^ f
它被评估为 (print_string "File ") ^ f
,但您期望的是
print_string ("File " ^ f)
"Folder"
情况也是如此。
更新
在更新的示例中,您有一个将两个参数应用于一个参数的函数。我想,而不是:
let rec visit tree = function
你想写
let rec visit = function
相当于
let rec visit tree = match tree with
问题是你已经将visit
写为列表上的函数,但在文件树上调用了它。
让我们将其更改为树上的函数,并使用List.iter
来遍历列表:
let print_files tree =
let rec visit = function
| File file ->
Printf.printf "file: %sn" file
| Folder (name, contents) ->
Printf.printf "folder: %sn" name;
List.iter visit contents in
visit tree
最后我通过以下方式解决了它:
let writeFilesFromTree tree =
let rec visit = function
| [] -> print_string "-n"
| File f :: t -> Printf.printf "file: %sn" f ; visit t
| Folder (name, contents) :: t ->
Printf.printf "name: %sn" name ;
visit contents ;
visit t in
visit tree;;
它仍然感觉根本不是一个最佳解决方案,而且我感觉我正在通过最后两次连续调用visit
来破坏尾递归。