# Encapsulating types for direct access

**URL:** https://forums.fsharp.org/t/encapsulating-types-for-direct-access/4520
**Category:** General
**Tags:** beginners
**Created:** [May 6, 2025, 9:39am UTC](https://forums.fsharp.org/t/encapsulating-types-for-direct-access/4520 "2025-05-06T09:39:37Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![altbodhi](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/altbodhi/32/1253_2.png) [@altbodhi](https://forums.fsharp.org/u/altbodhi)
#### Post date: [May 6, 2025, 9:39am UTC](https://forums.fsharp.org/t/encapsulating-types-for-direct-access/4520/1 "2025-05-06T09:39:37Z")

</div>

```auto
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?

---

<div class="post-metadata">

### Author: ![murphy](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/murphy/32/1373_2.png) [@murphy](https://forums.fsharp.org/u/murphy)
#### Post date: [May 6, 2025, 5:53pm UTC](https://forums.fsharp.org/t/encapsulating-types-for-direct-access/4520/2 "2025-05-06T17:53:57Z")

</div>

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 🤔

---

<div class="post-metadata">

### Author: ![altbodhi](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/altbodhi/32/1253_2.png) [@altbodhi](https://forums.fsharp.org/u/altbodhi)
#### Post date: [May 6, 2025, 11:41pm UTC](https://forums.fsharp.org/t/encapsulating-types-for-direct-access/4520/3 "2025-05-06T23:41:42Z")

</div>

Yes, I was wake up and think than senselessly do it.

---

<div class="post-metadata">

### Author: ![murphy](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/murphy/32/1373_2.png) [@murphy](https://forums.fsharp.org/u/murphy)
#### Post date: [May 6, 2025, 11:57pm UTC](https://forums.fsharp.org/t/encapsulating-types-for-direct-access/4520/4 "2025-05-06T23:57:39Z")

</div>

`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.

---

<div class="post-metadata">

### Author: ![altbodhi](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/altbodhi/32/1253_2.png) [@altbodhi](https://forums.fsharp.org/u/altbodhi)
#### Post date: [May 9, 2025, 11:05pm UTC](https://forums.fsharp.org/t/encapsulating-types-for-direct-access/4520/5 "2025-05-09T23:05:18Z")

</div>

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… 😅

```auto
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?

```auto
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).

---

<div class="post-metadata">

### Author: ![altbodhi](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/altbodhi/32/1253_2.png) [@altbodhi](https://forums.fsharp.org/u/altbodhi)
#### Post date: [May 14, 2025, 1:53am UTC](https://forums.fsharp.org/t/encapsulating-types-for-direct-access/4520/6 "2025-05-14T01:53:27Z")

</div>

I got nice answer in this [Инкапсуляция конструкторов размеченных объединений - F# - Киберфорум](https://www.cyberforum.ru/fsharp/thread3205313.html)  
Code very good but it noise by my opinion. Better using validate function than use DDD.
