I posted this question.
The link above reflects a question that I had regarding how to enforce reliance on a function to create a value for a client.
The solution is to have the client rely on Active Patterns that’s publicly exposed while maintaining the privacy of the Discriminated Union type. This will prevent a client from creating a value of it explicitly.
Here’s the solution:
namespace Mynamespace [<AutoOpen>] module File1 = type EmailAddress = private | Valid of string | Invalid of string let createEmailAddress (address:string) = if address.Length > 0 then Valid address else Invalid address let (|Valid|Invalid|) = function | Valid input -> Valid input | Invalid input -> Invalid input module File2 = let result = createEmailAddress "XXX" |> function | Valid email -> true | Invalid email -> false