Phantom Types in Gleam
blog.pd-andy.dev
blog.pd-andy.dev
https://stackoverflow.com/questions/3730019/why-not-use-doub...
I used to use it extensively in C++: beware though of (super long) compile errors while nesting them through templates params. :)
Edit: I was wrapping pointers for instance to not mix GPU and CPU memory addresses, to define a unidirectional flow of memory transfers between devices (and avoid manual synchronisation and tracking)... etc.
You could somehow define a state machine through types and ensure compositional coherence.
[1]: https://gist.github.com/rupertlssmith/88946c8d207d7ad64daf43...
The answer is structural typing (aka duck typing).
In a language with structural typing, two types are considered equivalent if they share the same structure. With phantom types we can have a single structure and disambiguate between different uses without touching the underling structure. There's no difference between Id(User) and Id(Post) at runtime, the annotation is purely a compile-time restraint.
In fact, because of typescript's structural typing, the only way to use phantom types in ts is to have some dummy field of type `never` that the type system can use to disambiguate between the two [1].
[1]: https://gist.github.com/GoNZooo/243b23702df1fae38c966ae18832...
Btw. is there a difference between these two:
(s: string): PlainText => <PlainText><any>s;
(s: string): PlainText => s as any as PlainText;
Syntax-wise I'd rather use the latter for it's more clear in typed JSX-context.