我正在尝试以递归方式浏览文件和文件夹的嵌套列表。虽然我这样做,但我想打印我访问的文件和文件夹的名称,但我做的事情非常错误。这就是我所拥有的:
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: %s\n" file
| Folder (name, contents) ->
Printf.printf "folder: %s\n" 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 `;'
答案 0 :(得分:1)
你忘了括号:
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
答案 1 :(得分:1)
问题在于您已将visit
作为函数写入列表,但在文件树上调用它。
让我们将其更改为树上的函数,并使用List.iter
来遍历列表:
let print_files tree =
let rec visit = function
| File file ->
Printf.printf "file: %s\n" file
| Folder (name, contents) ->
Printf.printf "folder: %s\n" name;
List.iter visit contents in
visit tree
答案 2 :(得分:0)
我最终以下列方式解决了这个问题:
let writeFilesFromTree 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;;
它仍然感觉不是最佳解决方案,我感觉我在最后两次连续调用visit
时破坏了尾递归。