简体   繁体   English

F#中的不可变Trie结构

[英]Immutable Trie structure in F#

I am playing around with the aho-corasick algorithm to try and get a little better with F#, and I ran across a problem with the Trie implementations, they are all mutable or can't be tail call optimized. 我正在使用aho-corasick算法来尝试使用F#更好一点,我遇到了Trie实现的问题,它们都是可变的或者不能进行尾调用优化。

The basic issue from what I can see is that immutable data structures have to be built "bottom up" since you can't change what they point to, so your options are either make them mutable, or find out the nodes as you go along(ie recurse in construction). 我可以看到的基本问题是,不可变数据结构必须“自下而上”构建,因为你不能改变他们所指向的内容,所以你的选择要么让它们变得可变,要么在你去的时候找出节点(即在施工中递归)。

Is there any way of making an immutable trie data structure with tail call optimizations on the construction?(and not lose efficiency by copying.) 有没有办法在构造上使用尾调用优化来创建一个不可变的trie数据结构?(而不是通过复制来降低效率)。

The tail call optimiation can be eliminated by using a continuation. 可以通过使用延续来消除尾调用优化。 Here's a sample where the key and value are string and int respectively 这是一个示例,其中键和值分别是stringint

type Trie = 
 | Data of string * int * Trie * Trie 
 | Leaf 

let Insert start key value = 
  let rec inner current withNode = 
    match current with
    | Data (currentKey, currentValue, left, right) ->
      if key < currentKey then
        inner left (fun left -> Data (currentKey, currentValue, left, right))
      else 
        inner right (fun right -> Data (currentKey, currentValue, left, right))
    | Leaf -> withNode (Data (key, value, Leaf, Leaf))
  inner start (fun x -> x)

Eliminating the copies is a bit more difficult if you want to stick with immutable structures 如果你想坚持使用不可变结构,消除副本会有点困难

I came across this post while researching for my code review post where I've implemented at immutable trie. 我在研究我的代码审查帖子时发现了这篇文章,我在不可变的trie中实现了这个帖子。

It is performant using maps for links rather than binary trees. 使用映射表示链接而不是二叉树是高性能的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM