I thought some more about my last example, and I talked to a Haskell programmer about it. The central problem – converting a Container<T>
to a Container<U>
when you have a type T that is convertible to U – turns out to be exactly the use case for Coercible
. I did some searching and found an old Rust RFC about this: https://github.com/rust-lang/rfcs/pull/91
Unfortunately, it hasn’t seen much attention since 2014.
Coercible seems like an ideal solution to a bunch of the inconveniences of the newtype pattern. With both delegation and Coercible, I think I’d find the newtype pattern convenient enough to use for this situation, reducing the need to relax the orphan rules.