I am trying to implement a trie data structure in F#.
I am having some problems.
I cannot debug the word insertion function. None of my breakpoint inside this function is reached something crashes but I don’t see any error.
Also I am having serious doubts if I implemented the thing right.
Anyway here is the code:
type TrieNode =
| SubNodes of char * bool * TrieNode list
| Nil
member this.Char = match this with | Nil -> ' '
| SubNodes(c,weh,subnodes) -> c
member this.GetChild(c:char) = match this with | Nil -> []
| SubNodes(c,weh,subnodes) ->[ (List.filter(fun (this:TrieNode) -> this.Char = c) subnodes).Head ]
member this.AWordEndsHere = match this with | Nil -> false
| SubNodes(c,weh,subnodes) -> weh
module TrieFunctions =
let rec insertWord (wordChars:char list) = function
| Nil -> SubNodes(wordChars.Head, false, [])
| SubNodes(c, weh, subnodes) as node ->
let child = node.GetChild(wordChars.Head)
if child = [] then
SubNodes(wordChars.Head,false,[insertWord wordChars.Tail node])
else
SubNodes(wordChars.Head,false,[insertWord wordChars.Tail child.Head])
type Trie(inner : TrieNode) =
member this.InsertWord(wordChars:char list) = TrieFunctions.insertWord(wordChars)
let trie = Trie(SubNodes(' ',false,List.empty)).InsertWord(['g';'i';'g';'i'])
So my questions are:
1. how can I get debug access to the insertWord function? Why am I not getting it now? Why am I not seeing an error?
2. How can I make the function insert word return a list of TrieNode objects so that I won’t have to wrap the call around square brackets (“[“,”]”). I think this is an error.
3. Any other advice you can give me on implementing this data structure in F# is welcomed I know I must be doing a lot of things wrong as I am very new to this language. I know for example that the word insertion function is flawed because it doesn’t check if the list is empty or not so it ends prematurely. I wanted to cross that bridge when I got to it.
Thank you in advance
Thank you in advance
You are probably failing to trigger your breakpoint because you aren’t fully applying
insertWords: it takes two curried parameters, but you’re only passing the single argumentwordCharsin. Perhaps you meant to define yourTrietype like this instead?Well, you could wrap all of your return values in
[]to make them singleton lists and then not wrap the recursive calls toinsertWords. However, it seems likely that there’s something wrong with your algorithm (either way), since you only ever get singleton lists…Note that at the moment you’re completely discarding the existing
subnodeslist – if you want to append to the front of it, use(insertWord wordChards.Tail node)::subnodesinstead. However, sometimes you’ll want to replace an existing entry rather than append a new one, which will require more effort.There are several issues. Here are a few to get you started:
Head, particularly since you don’t always know that your lists are non-empty when you’re calling it.Trie, you’re dropping all but the first character! Similarly, you need to reconsider your recursive calls too.TrieNodetype has a bit of a problem. Can you write out the resulting trie you would expect to see which just contains the two words"in"and"to"?