I don't know how could I write smarter/more elegant code for the add
function , it just seems so meaty and hard to read.
This trie only stores words and marks their end with a bool
.
type trie = Node of bool * (char * trie) list
let empty = Node (false, [])
let rec add w tr = match w, tr with
| [], Node (_, lvl_l) -> Node (true, lvl_l)
| wh :: wt, Node (b, lvl_l) ->
try let ins_point = (List.assoc wh lvl_l) in
Node(b, (wh, add wt ins_point)::(List.remove_assoc wh lvl_l))
with Not_found -> Node (b, (wh, add wt empty)::lvl_l)
let explode word =
let rec explode' i acc =
if i < 0 then acc else explode' (i-1) (word.[i] :: acc)
in explode' (String.length word - 1) []
Output Example :
# let x = add (explode "horror") empty;;
val x : trie =
Node (false,
[('h',
Node (false,
[('o',
Node (false,
[('r',
Node (false,
[('r',
Node (false, [('o', Node (false, [('r', Node (true, []))]))]))]))]))]))])
# let x = add (explode "horrific") x;;
val x : trie =
Node (false,
[('h',
Node (false,
[('o',
Node (false,
[('r',
Node (false,
[('r',
Node (false,
[('i',
Node (false,
[('f',
Node (false,
[('i', Node (false, [('c', Node (true, []))]))]))]));
('o', Node (false, [('r', Node (true, []))]))]))]))]))]))])