obj Sex = m:Male or f:Female; (* * The next two lines are not the best way to define Male and Female as enum * lits. Rather, Male and Female should be left as opaque types, values of * which can be constucted using symbolic (i.e, quoted) literals, or the normal * 0-ary opaque type constructor. *) val Male = "male"; val Female = "female"; (* * Here's a function of Sex, to be used to discuss binding of Sex-type values. *) op F(s:Sex); (* * And the following attempt at injection inference cannot work, since we * cannot infer that the string value "male" is necessarily of type Male, as * opposed to just type string, since, in fact, type Male *is* type string. * Hence, all the business of enum lits as strings has been a pile of caca, * TYPEWISE, since there's no handy way to use such strings as enum lit values. * The TYPEWISE qualifier here means that we get meaningful behavior, not just * the kind of type inference we might hope for. * * Since we can't infer that "male" is of type Male, even with the above * concrete obj def, we're not even close to being able to infer that "male" * of type Sex, which is what we ultimately want here. *) op main = (*begin*) ( F("male"); (* Can't work as hoped for, per preceding comment. *) F(Male("male")); (* Might work, but why would we even want it to, given * how clumsy it is? *) F(Male()) (* Works fine, if Male stays an opaque type. *) ); (*end;*) var s:Sex; var m:Male; var f:Female; (* * So, how do we construct a literal male value, of type Sex? The full-on way * would be * * Sex(Male()) * * since Male is the 0-ary constructor for the opaque type Male, and Sex is the * 1-ary (injection) constructor for the union type Sex. * * HOWEVER, if RSL wants to be nice, then in certain circumstances, it should * be possible to omit the injection function Sex, given that those * circumstances permit the checker to infer the injection. Yes, in fact, this * can happen. See implementation-notes for further details. *)