4

I am trying to build a trie in OCaml:

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);;

But this gives me the following error:

val findInsert : 'a -> ('a, 'b) trie list -> ('a, 'b) trie = <fun>
File "trie.ml", line 15, characters 54-62:
Error: Unbound value trieList

EDIT:: Thanks to Virgile I now have the a program that compiles:

(* 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);;

But when I try to run it I get this:

# 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

What do those numbers represent?

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
Ihmahr
  • 1,110
  • 1
  • 16
  • 25
  • If an answer to your existing question prompts a new question, please ask it in another post. Asking it in the same post means that what were good answers become bad answers. Also your secondary question may never be answered because everyone has already looked at your post. – Pascal Cuoq Jan 01 '13 at 19:38

2 Answers2

6

You shouldn't use let x = ... and y = ... in when y depends on x, as all identifiers bound by the unique let are supposed to be defined at the same time. Use let x = ... in let y = ... in instead, to ensure that x will be in scope when defining y. In your case, this becomes:

let Cons(k, v, trieList) = t in
let subTree = insert (key, value) (findInsert key trieList) in ...
Virgile
  • 9,724
  • 18
  • 42
3

When using the toplevel, if you define the same type twice, ocaml will see two types, not just one. As your two types have the same name trie, they are renamed trie/1017 and trie/1260. If you recompile the type declaration, you must recompile all other declarations that rely on this type so that they will use the new type and not the old one.

Other remark: you should never write

match foo with
| a -> let PATTERN = a in

you should use this instead:

match foo with
| PATTERN ->
Thomash
  • 6,339
  • 1
  • 30
  • 50