As we know, functional programming cuts the entity model we learned before to logical and data parts. It's clearly demonstrated in the example below:

The practice to use public properties is expected for entities as for functional programming. Moreover, the usage of getters and setters, which delegate private properties only discouraged and often ridiculed.
Just take a look at the way functional programming offers to avoid inconsistent states. It is reliable and straightforward: data structures are preferentially immutable.
The way to change such objects is cloning at first. If any part of the program is trying to change them, it must clone it first. Thus, the validation of any other program parts can be valid, and a modified object is a new instance. It is how the optimization of change detection performance happens. Deep comparisons are not required because the changed object is a new instance and the object references are no longer the same.
The undoubted advantage of immutability is the fact that you may not worry about tightly coupling. You are free to produce as many copies as you want, create derivative data structures, and make any manipulations on them. In doing so, you will be sure that the original data structure remains unchanged.
In this stage, you should beware of another widespread mistake when the developer trying to squeeze into the one function that has to be distributed through the multiple levels of abstraction. Pay special attention to what exactly you select the model level, not the service level.
Note, you should reuse as many generic functions as you can. Any suitable places can be and should be fitted by those functions. Still, if you cope with application-specific operations on the more complicated level, you should only provide a comprehensive set of dedicated functions for this model.