Idiomatic conditionals in F# I'm learning F#, and even though I'm able to do whatever I want, parts of my code looks really bad. I would love to get some suggestions on how to improve a couple of functions involving some conditional logic.

let stripLast (punct : char) (word : string) =
    if word.Length &gt; 0 &amp;&amp; word.LastIndexOf(punct) = word.Length - 1
    then word.Substring(0, word.Length - 1)
    else word

let countWord (dictionary : Dictionary&lt;string, int&gt;) word =
    if word = "" || (blacklisted word) then "" |&gt; ignore
    elif dictionary.ContainsKey(word)  then dictionary.[word] &lt;- dictionary.[word] + 1
    else dictionary.[word] &lt;- 1


I'm guessing there are ways to make these much more elegant. For instance, the second function uses side-effects on a Dictionary and has return type unit, but I added a branch where I had to use ignore in (probably) a silly way. Please don't change the functionality, but show me a nicer way to write the code.
This is probably the way I would write it:

let stripLast punct word =
  match String.length word with
  | n when n &gt; 0 &amp;&amp; word.[n-1] = punct -&gt; word.[..n-2]
  | _ -&gt; word

let countWord (dictionary : Dictionary&lt;_,_&gt;) = function
  | null | "" -&gt; ()
  | word when blacklisted word -&gt; ()
  | word -&gt;
    match dictionary.TryGetValue(word) with
    | true, n -&gt; dictionary.[word] &lt;- n + 1
    | _ -&gt; dictionary.Add(word, 1)


Here's a rundown of the changes:

In stripLast:


Use String.length instead of a type annotation (punct can also be inferred)
Capture the length (which is used multiple times) using pattern matching
Check only the last char (LastIndexOf searches the whole string)
Use string slicing over Substring for conciseness


In countWord:


Allow the type args for Dictionary&lt;_,_&gt; to be inferred
Use pattern matching to clearly show the cases to be handled
Replace calls to ContainsKey and Item ([]) with one call to TryGetValue


A more functional approach, assuming you have a list of words, might be:

words 
  |&gt; Seq.countBy (stripLast stripChar)
  |&gt; Seq.filter (fun (word, _) -&gt;
    match word with
    | null | "" -&gt; false
    | _ -&gt; not (blacklisted word))