It cites the Haskell work: https://github.com/jswrenn/rfcs/blob/safer-transmute/text/00...
I’m thinking about a similar sort of coercion system for a language project, and it’s good to have a slightly broader view of the design space. This area hasn’t been very well explored yet, not just in terms of semantics, but also developer ergonomics: most of the time you want to hide representations for convenience, but when considering safe coercions, you really want to make it possible to talk about them explicitly & precisely.
This feature is also very subtle, and right at the very edge of the type system, so it’s extremely easy to break soundness here, usually by failing to consider things like variance. The reason “roles” were added to GHC in the first place isn’t just because of the issue with type families / associated types mentioned in that RFC; it’s also because anything that provides a safe API atop unsafe internals could also be used to violate soundness, especially in conjunction with mutation. The classic examples are: 1. coercing “container of A” to “container of B” using the coercion from A to B, then inserting a B that is not a valid A, either in its value or just because A and B have incompatible trait instances (like ordering or hashing). You need to be able to disallow conversions between things even if they have identical representations.
This lets me safely ignore the rest of the article.
To expand on that, for those in the audience:
In Haskell, a functor is a type constructor (like “list”, “optional”, “future”, “I/O request”, &c.) with a way to map a function over it, covariantly, in a way that preserves its structure—i.e. without changing the shape of the container or structure of the action represented by the constructor, just the contained elements or produced result.
This is based on the more general notion of a functor in mathematics, which is a mapping between categories. The Haskell version is much more constrained, though: it only maps between Haskell types, and it’s parametric (iow completely generic), not just any old mapping.
While in C++, a functor is a completely different thing: an object that can be called like a function. It’s thus equivalent to a closure, where the object fields are the captured values. And that sounds like the description being used here.