Functional programming 在Ocaml中打印trie

Functional programming 在Ocaml中打印trie,functional-programming,ocaml,nested-lists,trie,Functional Programming,Ocaml,Nested Lists,Trie,下面列出的每个功能都按预期工作。(最后一个除外) 我试图使to_list工作,我希望它返回列表的字符列表,但到目前为止,我只通过简单的打印实现了它返回单元 type trie = Trie of bool * (char * trie) list let empty = Trie (false, []) let explode wd = (*breaks up a word in a list of chars*) let rec exp i acc = if i =

下面列出的每个功能都按预期工作。(最后一个除外)

我试图使
to_list
工作,我希望它返回
列表
字符列表
,但到目前为止,我只通过简单的
打印实现了它
返回
单元

type trie = Trie of bool * (char * trie) list
let empty = Trie (false, [])

let explode wd = (*breaks up a word in a list of chars*)
    let rec exp i acc =
        if i = -1 then acc else exp (i-1) (wd.[i]::acc) in 
        exp (String.length wd - 1) []

let insert tr wd = (*insert a word into the trie*)
let rec insert' wd tr = match wd, tr with 
    | [], Trie (_, l) -> Trie (true, l)
    | wh::wt, Trie (b, l) ->
        try Trie(b, (wh, insert' wt (List.assoc wh l))::List.remove_assoc wh l)
        with Not_found -> Trie (b, (wh, insert' wt empty) :: l)
        in insert' (explode wd) tr

let from_list = List.fold_left insert empty  (*makes trie from string list*)

let to_list tr = (*prints all trie words*)
    let rec to_list' (Trie (b, l)) acc = 
        if b then
            (
                List.iter print_char (List.rev acc); 
                print_char '\n'
            )
        else ();
        List.iter (fun (c, t) -> to_list' t (c::acc)) l in
    to_list' tr []
编辑:多亏@Goswin von Brederlow,我使我的
to_列表
打印功能更加清晰

我尝试的是:

let to_list tr = (*fails at compile time*)
    let rec to_list' acc = function
        | Trie(_, []) -> [List.rev acc]
        | Trie(true, (c, h)::_) -> (List.rev acc) :: to_list' (c::acc) h
        | Trie(_, l) -> List.map (fun (c, t) -> to_list' (c::acc) t) in
        to_list' [] a tr
例如:

let t = from_list ["hello"; "hell"; "helsinki"; "here"];;
# to_list t;;
here
helsinki
hell
hello
- : unit = ()

它失败是因为
List.map
只能返回类型
'a List
,而不能返回任何
n深度嵌套列表

List.map可以返回列表列表。这不是你的问题

您说您的
to_list
函数没有编译,但您没有显示错误。这使得提供建议变得更加困难

我在代码中看到的第一个问题是:

List.map (fun (c, t) -> to_list' (c::acc) t)

这里只有一个论点。但一般来说,您需要提供两个参数:一个函数(您拥有的)和一个列表(您没有)。有两种合理的方法可以做到这一点:让
map
返回列表,然后将其展平,或者执行累加器。我将给出第二个,因为它更有效,也不复杂:

let to_list trie =
  let rec recur acc chars (Trie (word_here, entries)) =
    let acc =
      match entries with
      | [] -> acc
      | _ ->
        List.fold_left (fun acc (char, trie) ->
            recur acc (char::chars) trie)
          acc entries in
    if word_here then List.rev chars::acc
    else acc in
  recur [] [] trie

您想要什么输出,得到什么错误?字符列表的列表毫无意义。你不是指一列字符串吗?这样从列表(到列表trie)就可以工作了。如果from_list和to_list使用不同的列表类型,则任何模块都会对我产生影响。请尝试插入[“hello”、“hello”、“hella”],您的
| Trie(true,(c,t):::)->
将不起作用。您需要
| Trie(true,l)->
在那里。我建议把它一分为二。首先检查true并将单词添加到累加器中,然后迭代子级。注意:
| Trie(,[])->
是没有意义的,其他的例子已经涵盖了这一点。@GoswinvonBrederlow感谢您指出,我的第一次尝试只是为了得到这个函数的逻辑,所以我尝试了简单的
打印
,然后我想把Trie中的每个单词作为字符列表,因为我已经有了一个
to_string
函数,它可以输入一个
字符列表
并从中生成一个
字符串
,我只是不想把它贴在这里,这个问题中的代码已经太多了。我真的错过了stdlib中的string.of_列表和string.to_列表。@Oleg我认为它们从来没有出现过