在OCaml中创建char Trie

时间:2018-09-24 00:09:49

标签: functional-programming ocaml variant

我正在尝试在OCaml中构建初始Trie结构,其中边缘为char。因此,字符串“ ESK”将被映射为:

label_features = [] dic = {} dic['chipotle']='mexican' dic['burger']='american' label_features.append((dic,'food')) NaiveBayesClassifier.train(label_features) >><nltk.classify.naivebayes.NaiveBayesClassifier object at 0x000001704916BDD8>

我对此的定义是:

[('E', [('S', [('K', [])])])]

但是,在通过以下方式实现type trie = Trie of (char * trie) list 函数时:

add

对于 let rec add_string str = let key = String.get str 0 in if String.length str = 1 then (key, empty_trie) :: [] else (key, add_string (tail str)) :: [] ,编译器给我:

add (tail str)

我对此感到有点困惑,因为我没有将Error: This expression has type (char * trie) list but an expression was expected of type trie 定义为trie

(char * trie) list就是tail,而let tail str = String.slice str 1 (String.length str)empty_trie

2 个答案:

答案 0 :(得分:1)

请注意,编写该函数的更惯用的方式是

sealed trait Expr[T]
case class IntExpr(i: Int) extends Expr[Int]
case class BoolExpr(b: Boolean) extends Expr[Boolean]

def eval[T](e: Expr[T]): T = e match {
  case IntExpr(i) => i
  case BoolExpr(b) => b
}

然后let rec add_string str = let key = str.[0] in if String.length str = 1 then Trie [key, empty_trie] else Trie [key, add_string (tail str)] 还有两个问题:首先,它在每次迭代时都重新分配一个新字符串。跟踪当前位置更加简单有效:

add_string

第二个问题是该函数的名称不正确,因为它不会将字符串添加到现有的trie,而是从字符串构建了trie:let add_string str = let rec add_string_aux pos str = if pos = String.length str then empty_trie else let key = str.[pos] in Trie [key, add_string_aux (pos+1) str] in add_string_aux 0 str from_string可能是更好的名称。 / p>

答案 1 :(得分:0)

已解决。 Trie应该明确使用:

let rec add_string str =
  let key = String.get str 0 in
  if String.length str = 1 then
    (key, empty_trie) :: []
  else
    (key, Trie (add_string (tail str))) :: []

这将导致add_string "ESK"产生:

(char * trie) list = [('E', Trie [('S', Trie [('K', Trie [])])])]