Skip to content

Instantly share code, notes, and snippets.

@Nnwww
Last active November 23, 2015 21:04
Show Gist options
  • Save Nnwww/682f5a8331326431086b to your computer and use it in GitHub Desktop.
Save Nnwww/682f5a8331326431086b to your computer and use it in GitHub Desktop.
Trie in OCaml (I can't come up with smart implementation)
type trie = Trie of int option * char_to_children
and char_to_children = (char * trie) list
let empty =
Trie (None, [])
let example =
Trie (None,
[('i', Trie (Some 11,
[('n', Trie (Some 5, [('n', Trie (Some 9, []))]))]));
('t',
Trie (None,
[('e',
Trie (None,
[('n', Trie (Some 12, [])); ('d', Trie (Some 4, []));
('a', Trie (Some 3, []))]));
('o', Trie (Some 7, []))]));
('A', Trie (Some 15, []))])
let rec find ~fn = function
| [] -> None
| hd :: tl -> if fn hd then Some hd else find tl ~fn
let children_from_char children c =
let res = find children ~fn:
(function
| (x, _) -> if x = c then true else false)
in
match res with
| None -> None
| Some (fst, snd) -> Some snd
let update_children_list children c cons_trie =
let update (update, acc) ((fst, Trie(x, xs)) as e) =
if fst = c then
(true, ( fst, cons_trie (Some(x, xs)) ) :: acc)
else
(update || false, e :: acc)
in
let (success, result) = List.fold_left update (false, []) children in
if success then result
else (c, cons_trie None) :: result
let update_children children c trie =
update_children_list children c (fun _ -> trie)
let char_of_string word =
let len = String.length word in
let rec loop acc idx =
if idx < 0 then acc else loop (String.get word idx :: acc) (idx - 1)
in
loop [] (len - 1)
let lookup trie word =
let rec loop wl (Trie (x, xs)) = match (wl, xs) with
| (c :: ctl, _ :: _) ->
begin match children_from_char xs c with
| None -> None
| Some s -> loop ctl s
end
| (c :: ctl, []) -> None
| ([], _) -> x
in
loop (char_of_string word) trie
let insert (Trie(x, children)) word value =
let rec update_trie x xs = function
| [] -> Trie(Some value, xs)
| (c :: tl) as wl -> Trie (x, update_list xs wl)
and update_list xs = function
| [] -> invalid_arg "The length of a word is not enough."
| c :: tl ->
update_children_list xs c
(function
| None -> update_trie None [] tl
| Some (x, xs) -> update_trie x xs tl)
in
update_trie x children (char_of_string word)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment