File Trees
type 'a rtree = Node of 'a * 'a rtree list
We can think of a file system as a tree of directories and files.
In this problem, we will be converting a list of file paths into an
rtree. For example, given the paths
dir1/file1 dir1/file2 dir2/dir3/file1 dir2/file1
we can construct the nonempty tree file_tree "." paths:
Node ( "." , [ Node ("dir1", [Node ("file1", []); Node ("file2", [])]) ; Node ("dir2", [Node ("dir3", [Node ("file1", [])]); Node ("file1", [])]) ] )
which can be visualized as follows.
. ├──dir1 │ ├──file1 │ └──file2 └──dir2 ├──dir3 │ └──file1 └──file1
In this representation, a file is a leaf node, i.e., a node with no
children. We will take a very relaxed definition of a file name: a
file name can be any sequence of characters not including ''/.
This means that every string is a valid path (even "foo/bar///baz").
In particular, "" represents the file with the empty string as its
name (this isn't realistic, but it makes the problem easier).
Implement the function
val file_tree : string -> string list -> string rtree
so that file_tree root file_paths is an rtree consisting of all
the paths given in file_paths, and whose root value is root. It
is possible for file_paths to contain duplicates, but if it does
not, there should be a one-to-one correspondence between paths from
the root to the leaves of the tree and paths in file_paths.
Note. The order of the children at each node isn't important, as
long as the correspondence above holds. One way to sanity-check
your implementation: if you strip the root off every path from
the root to a leaf of file_tree root file_paths, you should get
back file_paths (potentially in a different order).
Examples
let paths = ["dir1/file1"; "dir1/file2"; "dir2/dir3/file1"; "dir2/file1"] let _ = assert (file_tree "." paths = Node ( "." , [ Node ("dir1", [Node ("file1", []); Node ("file2", [])]) ; Node ("dir2", [Node ("dir3", [Node ("file1", [])]); Node ("file1", [])]) ] )) let _ = assert (file_tree "root" [] = Node ("root", [])) let _ = assert (file_tree "root" ["a"] = Node ("root", [Node ("a", [])]))