我正在尝试在OCaml中构建trie:
type ('a, 'b) trie = Nil | Cons of 'a * 'b option * ('a, 'b) trie list;;
(* find place to insert key in a list of tries *)
let rec findInsert key x =
match x with
[] -> Nil
| x::xs -> let Cons(k, _, _) = x in
if key = k then x else findInsert key xs;;
(* inser pair in a trie *)
let rec insert ( key, value ) trie =
match trie with
Nil -> Cons(key, value, [])
| t -> let Cons(k, v, trieList) = t and
subTree = insert (key, value) (findInsert key trieList) and
newSubTree = subTree::trieList in
Cons(k, v, newSubTree);;
但是这给了我以下错误:
val findInsert : 'a -> ('a, 'b) trie list -> ('a, 'b) trie = <fun>
File "trie.ml", line 15, characters 54-62:
Error: Unbound value trieList
EDIT :: 感谢Virgile我现在有一个编译的程序:
(* insert pair in a trie *)
let rec insert ( key, value ) trie =
match trie with
Nil -> Cons(key, value, [])
| t ->
let Cons(k, v, trieList) = t in
let subTree = insert (key, value) (findInsert key trieList) in
Cons(k, v, subTree::trieList);;
但是当我尝试运行它时,我得到了这个:
# let t = Cons(3, Some 4, []);;
val t : (int, int) trie = Cons (3, Some 4, [])
# insert (4, Some 5) t;;
Error: This expression has type (int, int) trie/1017
but an expression was expected of type (int, int) trie/1260
这些数字代表什么?
答案 0 :(得分:6)
当let x = ... and y = ... in
取决于y
时,您不应使用x
,因为应该同时定义由唯一let
绑定的所有标识符。请改为使用let x = ... in let y = ... in
,以确保在定义x
时y
将在范围内。
在你的情况下,这变为:
let Cons(k, v, trieList) = t in
let subTree = insert (key, value) (findInsert key trieList) in ...
答案 1 :(得分:3)
使用顶层时,如果两次定义相同的类型,ocaml将看到两种类型,而不仅仅是一种。由于您的两种类型具有相同的名称trie
,因此会将其重命名为trie/1017
和trie/1260
。如果重新编译类型声明,则必须重新编译依赖于此类型的所有其他声明,以便它们使用新类型而不是旧类型。
其他评论:你永远不应该写
match foo with
| a -> let PATTERN = a in
你应该使用它:
match foo with
| PATTERN ->