obj Sex = m:Male or f:Female; (* * The next two lines simply must be bogus. Rather, Male and Female should be * left as opaque types, values of which can be consstucted using symbolic * (i.e, quoted) literals. *) obj Male = "male"; obj 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 * since there's no handy way to use such strings as enum lit values. * * 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. *) var x:integer; op main = ( f(x); (* Wrong for sure *) 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. *) ); 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. *)