module UserMod =
type User =
private
| Young of age: uint
| Audlt of age: uint
let createUser (age: uint) : User =
if age > 17u then Audlt age else Young age
let get = function Audlt a -> a | Young y -> y
module Test =
let user = UserMod.createUser 12u
I can create user, but I not get access to age from Test module. Why? It possible or not?
You declared the constructors private
, so they are hidden outside the containing module. You could use internal
access instead to allow access within the same compilation unit 
Yes, I was wake up and think than senselessly do it.
internal
access can even be granted to another assembly using the [<System.Runtime.CompilerServices.InternalsVisibleTo("…")>]
attribute, which could be useful if you wanted to move your tests into a different compilation unit.
No, I rethink. In C# I have private constructor but still can acess to defintion class/record for use pattern match in place. In this case F# this is don’t make sense because after create value of type getter possible only from own module. This forces us to validate records every time before using or using OOP.
UPD. Finaly, i think that DDD on records is not possible as well as in OOP with a private constructor, but with public getters. it is sad.
Few minutes later… 
class Person
{
public string Name { get; }
public int Age { get; }
public Person(string name, int age)
{
if (age < 0) throw new Exception($"{nameof(age)} is negative");
Name = name;
Age = age;
}
public static void Example()
{
var p = new Person("Bob", 12);
Console.Write(p.Name);
}
}
- OOP approach for DDD
FP approach for same is near?
module Person =
type T = private { name: string; age: int }
let create (name, age) =
if age < 0 then
None
else
Some({ name = name; age = age })
let age = fun x -> x.age
let name = fun x -> x.name
let p = Person.create ("Bob",2) |> Option.get
p |> Person.name |> printfn "%s"
verbose but explicit. Any ideas?
UPD also can to use with member
but it make not record, it will be like as raw pointer in C with same pieces aka member(public fields).
I got nice answer in this Инкапсуляция конструкторов размеченных объединений - F# - Киберфорум
Code very good but it noise by my opinion. Better using validate function than use DDD.