Inspectors & Deconstruction on Unions in a list
Fundamentally, for working with DUs, there is no other way. A DU represents values that can be "either this or that". This means that, when you're looking at one of these values, your code has to handle all possible options of what that value can be, otherwise your program will simply not know what to do for certain cases at runtime. There is no way around it.

That said, you can express this basic idea in different ways.

First, you can use the function keyword to shorten the pattern match a bit. let f = function is just a shorthand for let f x = match x with:

let IsTrue = function Valid _ -&gt; true | _ -&gt; false


Second, you can express IsFalse as a negation of IsTrue:

let IsFalse = not &lt;&lt; IsTrue


Alternatively, you could extract the pattern matching part into a function (commonly referred to as "catamorphism"):

let inline validCata ifValue ifError = function Value x -&gt; ifValue x | Error x -&gt; ifError x


and then express the other functions in terms of it:

let inline IsTrue x = validCata (ct true) (ct false) x
let inline IsFalse x = validCata (ct false) (ct true) x
let inline Value x = validCata id (fun _ -&gt; failwith "") x
let inline Error x = validCata (fun _ -&gt; failwith "") id x


(where ct is a trivial constant function, which is sadly missing in F# standard library)

As for the CreateThing function, let me see if I understood the intent correctly: you're trying to validate the sequence of numbers and bail on the first error, returning it; or return the list of numbers if all of them are valid.

If this is the correct intent, you don't need to wrap each number in a Valid at all. Just run the validation function on them until it returns an error, and if it doesn't, return the original list. To run a function on a sequence and stop when it hits the first time, there is a handy library function Seq.tryPick:

let errorFor i =
    if i = 3 then Some "no threes yo" else None

let createThing inputs = 
    let firstError = Seq.tryPick errorFor inputs
    match firstError with
    | Some err -&gt; Invalid err
    | None -&gt; Valid { Thing.Values = List.ofSeq inputs }


If you hit this sort of problem often, and really want to use Valid as a general-purpose mechanism for dealing with errors, you can extract the "run sequence until error" part as a reusable thing:

let validSeq (s: Valid&lt;'a&gt; seq) : Valid&lt;'a list&gt; =
    let getError = function Valid _ -&gt; None | Error err -&gt; Some err
    let getValue = function Valid x -&gt; x | Error _ -&gt; Unchecked.defaultOf&lt;'a&gt;
    let lst = List.ofSeq s
    match List.tryPick getError lst with
    | Some err -&gt; Error err
    | None -&gt; lst |&gt; List.map getValue |&gt; Valid

let validMap f = function
    | Value v -&gt; Valid (f v)
    | Error err -&gt; Error err

let createThing inputs = 
    inputs
    |&gt; Seq.map ValidateNumber 
    |&gt; validSeq 
    |&gt; validMap (fun vs -&gt; { Thing.Values = vs })


(note that here I have also extracted validMap as a reusable thing)

Final note: unless you have actually hit (and measured) performance issues, don't work with sequences, work with lists instead. Since F# is not pure, running sequences multiple times can be expensive and unpredictable.