Defining a zip code string
The solution can be made cleaner by re-arranging the order of the arguments and using pointfree style.

let StringOfLengthConstructor&lt;'c&gt; (length : int) (defaultConstructor : string -&gt; 'c) (input : string) =
    match input with
    | x when x &lt;&gt; null &amp;&amp; x.Length = length -&gt; Some (defaultConstructor input)
    | _ -&gt; None

type String3 = String3 of string
let String3 = StringOfLengthConstructor 3 String3


However, I don't think that String5 * (String4 option) is a good definition of a zip code. The code should be validating on more than just the string length.