words_in_trie: trie -> (char list list -> 'a) -> 'a
all_words: trie ref list -> (char list list -> 'a) -> 'a
然后用它来调用它们 有趣的all_entries t = all_words t(fn l => map(fn w => String.implode w)l);
这必须通过延续来完成。我用非延续形式写了它,如下:
fun wt Empty = [[]]
|wt (Node(c,rl)) = map (fn (l) => c::l) (aw rl)
and aw [] = []
|aw [h] = wt (!h)
|aw (h::t) = (wt (!h))@(aw t)
但我无法弄清楚如何将它们转换为延续形式! 这是我到目前为止所做的,但它不起作用:
fun words_in_trie Empty cont = cont[]
|words_in_trie (Node(c,rl)) cont = (all_words rl (fn r=> cont(c::r)))
and all_words [h] cont = words_in_trie (!h) cont
|all_words (h::t) cont = (words_in_trie (!h) cont)@(all_words t cont)
我已经坚持了很久,我会感激任何帮助。
答案 0 :(得分:2)
由于对continuation的输入是单词的后缀,你知道在调用下一个continuation之后,结果必须更接近trie中的单词列表,并且仍然是单词的后缀。您可以使用它来确定延续应该做的是在trie之前添加下一个字母(给定一个字符列表列表,它将为字符串中的每个字符列表添加一个字符。)
fun words_in_trie Empty cont = cont[]
如果你传递的特里是Empty
,那么你在该特里有一个字,这是一个空字符串。您想要的结果是[""]
。回想一下,最后一个延续会将列表中的每个char list
转换为string
,因此为了获得该结果,您需要为其传递一个空char list
的列表,以便进行转换
|words_in_trie (Node(c,rl)) cont = (all_words rl (fn r=> cont(c::r)))
召回:延续的类型是char list list -> 'a
。 c
是char
,因此不能将其r
添加到char list list
类型。
all_words
会返回尝试列表rl
中包含的所有单词的列表,您希望将这些单词应用于继续(其中所有字符都包含在trie中)。您必须构建延续,以便除了从节点上的节点前面添加所有字符外,它还会从当前节点预先添加char
c
。您正在寻找的是这样的:
fn x => cont (map (fn y => c::y) x)
上面的内容会c
添加到列表中的每个char list
,然后将其传递到下一个续集,然后继续下一个char
。
您的all_words
功能对我来说很合适。