2015-04-15 2 views
1

Код в walkTree просматривает дерево файлов, представленное в списке fileTree узлов. Он делает то, что я хочу, чтобы рекурсивно печатать каждую запись в дереве. Но я чувствую, что это может быть значительно улучшено. Я также думаю, что я саботирую хвостовую рекурсию, запустив 2 заявления о посещении в конце сопоставления patern.Как можно улучшить эту рекурсивную функцию?

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 

Что было бы лучшим способом сделать это?

ответ

3

По крайней мере, я бы отделить list и fileTree соответствия:

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 
+0

Вы можете использовать взаимную рекурсию в ветви папки, чтобы вызвать внешний список List.iter в списке (один раз с именем). – nlucaroni

+0

Отличный ответ, спасибо! – GiantSquid

Смежные вопросы