To, co próbujesz zrobić, jest nazywane wzorem równości i nie jest dostarczane przez Objective Caml. Wzorce obiektywu Camla są statyczne i czysto strukturalne. To znaczy, czy wartość pasuje do wzorca zależy wyłącznie od struktury wartości, i w sposób określony podczas kompilacji. Na przykład: (_, _)::tail
to wzór pasujący do dowolnej niepustej listy, której głowa to para. (identifier, value)::tail
dopasowuje dokładnie te same wartości; jedyną różnicą jest to, że ta ostatnia wiąże dwie kolejne nazwy: identifier
i value
.
Chociaż niektóre języki mają wzorce równości, istnieją nietrywialne względy praktyczne, które sprawiają, że są kłopotliwe. Która równość? Równość fizyczna (==
w Ocaml), równość strukturalna (=
w Ocaml), czy też zależność od typu zależna od typu? Ponadto, w Ocaml, istnieje wyraźne wskazanie składniowe, które nazwy są wiążące i które nazwy odnoszą się do wcześniej powiązanych wartości: dowolny mały identyfikator we wzorze jest spoiwem. Te dwa powody wyjaśniają, dlaczego Ocaml nie ma wypalonych wzorów równości. Idiomatyczny sposób wyrażenia wzoru równości w Ocaml jest w straży. W ten sposób natychmiast staje się jasne, że dopasowanie nie ma charakteru strukturalnego, że nie jest związane tym dopasowaniem do wzorca i które z nich jest równe. Co do brzydkiego, to jest w oku patrzącego - jak zwykły programista Ocaml, uważam wzorce równości za brzydkie (z powyższych powodów).
match bindings with
| (id, value)::tail when id = identifier -> value
| (_, _)::tail -> getValue identifier tail
| [] -> -1
w F #, masz inną możliwość: active patterns, który pozwoli Ci wstępnie określić strażników, które dotyczą pojedyncze miejsce w strukturze.
Twoje oryginalne podejście przypomina mi zjednoczenie Prologu, jest raczej deklaratywne niż funkcjonalne. – ron