Serializing monads
See original GitHub issueHi guys,
I have an unorthodox but really easy request. I hope you will find it reasonable enough.
It would be great if you could provide constants to access the data internals of Maybe and Result types (.value
and .error
properties).
Alternatively, you could add to the specs those data internals, so that if they change in the future, you consider it a breaking change and a SEMVER major release.
The reason is we need to deserialize monads and to do so we need to be coupled to these internals.
If you want more detail:
Context
We have a client with Redux that stores the app state in local storage, thus serializing all state. We want to store monads in the state. We know it is a bad practice to store classes in Redux, but Maybes and Results are data types that hold state, and they make much sense to be stored.
The Maybe and Result types serialize correctly to the following examples:
{variant: 'Just', value: 4}
{variant: 'Nothing'}
{variant: 'Ok', value: 4}
{variant: 'Err', error: 'hi!'}
We make our reducers detect the de-serialization action, and re-create the monads from the objects using Maybe.just(...)
, Maybe.nothing()
, and so on.
The Problem
In order to de-serialize the monads, we need to be coupled to the object’s internals: .variant
, .value
, and .error
.
The Variant property is well specified in your docs, and in fact we are using the lib’s constants Variant.Just
, Variant.Nothing
, etc. But the other internals are not specified (because they are internals), and as such are subject to possible change without notice.
If this change causes a major release, it allows this coupling because it is then our responsibility to keep our code consistent with the update. If these internals are exposed through a constant, then you can change them without provoking a breaking change.
Why not a deserialize method
Deserializing involves type refinement from input source, it is a whole other field in itself, and it can devolve into libraries as complex as io-ts, so in my humble opinion, it doesn’t make sense as a true-myth responsibility, but belonging to userland.
Thank you for your attention!
Issue Analytics
- State:
- Created 4 years ago
- Comments:12 (6 by maintainers)
Top GitHub Comments
Thanks for the great writeup! This is totally a use case we should support.
The obvious alternative that occurs to me, instead of making those invariants hold (in case we find a better/faster/lighter-weight way to do this in the future) is for us to supply a
toJSON()
method so thatJSON.stringify()
does the right thing, supplying sufficient information for serialization and deserialization.(And the same for
Result
.)I think that would solve this in a way that would give nice public API that Just Works™ for the normal serialization/deserialization approach, while leaving private internals private. Thoughts?
Released in 3.1.0! Thanks again!