This sounds very similar to O'Caml's polymorphic variants, which you can read about here: http://caml.inria.fr/pub/docs/manual-ocaml/manual006.html#toc36. That link goes through some of the positives and negatives with the approach.
On Tue, Aug 27, 2013 at 3:58 PM, Bill Myers <bill_my...@outlook.com> wrote: > I was reading a proposal about adding "datasort refinements" to make enum > variants first-class types, and it seems to me there is a simpler and more > effective way of solving the problem. > > The idea is that if A, B and C are types, then "A | B | C" is a > "structural" enum type that can be either A, B or C. > > In addition, A can be implicitly converted to "A | B", "A | B" can be > implicitly converted to "A | B | C", and also "(A | B) | C" and "A | (B | > C)" are equivalent to "A | B | C", and finally "C | B | A" is equivalent to > "A | B | C" (to support the latter, the implementation needs to sort > variants in some arbitrary total order before assigning tag numbers). > > Furthermore, a way to bind variables to an "or" pattern is introduced to > allow to convert "A | B | C" to "A | B" in the case that it holds an A or a > B. > > This way, one can rewrite Option as a type alias like this: > struct Some<T>(T); > struct None; > > type Option<T> = None | Some<T>; > > Which is like the current Option, but also makes None and Some<T> > first-class types. > > The current enum syntax can remain as syntax sugar for the above code. > > The only issue I see is what to do for code such as "let mut x = Some(3); > x = None;": with this proposal, Some and None are separate unrelated types, > so we either have this code emit an error, or x must be given the type > "Some<int> | None" automatically, which however can lead to obscure error > messages if one mistakenly attempts to assign a string to it causing the > type to become "Some<int> | None | ~str" (i.e. the user might be told than > a match is not exhaustive because it does not handle the "~str" case, > rather than that they assigned a ~str to an Option-typed variable). > > It should be possible to allow this, and make the error-emitting code use > heuristics to figure out whether it is more likely that the user assigned a > value of the wrong type, or used an enum improperly (for example, by > looking at whether the implicitly created enum type is ever written > explicitly in the source, and whether the deduced structural enum type is > being used in places that require a non-enum type). > > Alternatively, one can stipulate that only types that are structs, or that > are structs marked "enum struct" or "case struct" or similar can become > part of an inferred structural enum, but this seems unappealing. > > Note that some structural enums can change representations depending > generic instantiation, since "T | int" becomes just "int" if T = int, while > it is "~str | int" if T = ~str (and similar for "Some<T> | Some<int>"), but > this should not be a problem. > > > _______________________________________________ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > >
_______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev