Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Phantom Types in Gleam (pd-andy.dev)
35 points by pd-andy on Feb 27, 2021 | hide | past | favorite | 11 comments


I know it's a toy example, but it's a _really bad idea_ to use a float as a backing type for currency.

https://stackoverflow.com/questions/3730019/why-not-use-doub...


Ha yes, very true!


Have you worked in finance?


This is a good post and technique in general.

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.


Using phantom types in state machine transitions is really cool, yeah. I came across a little gist that explored that idea in Elm [1] the other day, actually.

[1]: https://gist.github.com/rupertlssmith/88946c8d207d7ad64daf43...


Amusing to see "even PHP" in there, as the author of the static analysis tool that makes that possible.


It's kind of amusing reading this as a Typescript dev because I'm so used to Typescript's expressiveness I couldn't really work out which trick it was trying to tell me was novel.

The answer is structural typing (aka duck typing).


Not quite. I guess in some ways phantom types achieve the opposite of structural 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...


Holy smokes, that would be irritating :D

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.


As far as I know those two are equivalent. Definitely slightly clunkier, but is what it is.


Yes, exactly, it's because of Structural Typing that you have to implement Phantom Types in that hacky way rather than Structural Typing being the "trick".




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: