vypadá podobně jako volání funkce, ale znovu opakuji, konstruktory žádné funkce nejsou
Můžeš prosím rozvést, proč tak zdůrazňuješ tuto skutečnost?
type contact =
| NoContact
| Address(string, string, string)
| Phone(string);
Doufám, že nebudu předbíhat: Jde nějak přidat omezení na ten string u Phone, že má být maximálně deset znaků dlouhý (například)?
Můžeš prosím rozvést, proč tak zdůrazňuješ tuto skutečnost?
Jeden z rozdílů je v automatické generalizaci. Například tohle funguje
let id = (x) => x; let x = Some(id);
a x
má očekávaný typ option(('a) => 'a)
. Zatímco tohle nefunguje
let some(x) = Some(x); let x' = some(id);
x'
dostane typ option(('_a) => '_a)
a kompilátor vypisuje chybu This expression's type contains type variables that can't be generalized. Rozdíl je jen v tom, že jednou používáme konstruktor Some
a podruhé funkci some
. Je to důsledkem relaxed value restriction, což je omezení, které dovoluje generalizovat pouze typy hodnot (a mezi hodnoty spadají konstruktory a nespadají tam volání funkcí).
Jde nějak přidat omezení na ten string u Phone, že má být maximálně deset znaků dlouhý (například)?
Jde vytvořit typ, který uvnitř bude string, ale hodnoty tohoto typu půjde vytvářet pouze určitými funkcemi. Vynutit omezení na délku pak půjde uvnitř těch funkcí. Například
module Phone: { type t = pri string; let create: string => t; } = { type t = string; let create = (str) => if (String.length(str) > 10) { failwith("Blah") } else { str }; }; let p = Phone.create("1234"); /* Tohle hlasi chybu: This expression has type string but an expression was expected of type Phone.t let p': Phone.t = "1234"; */ /* Phone.t lze prevest na string. */ print_endline(p :> string);