2016-06-22 3 views
17

Ich stieß heute auf eine Kuriosität in der F # -Mustervergleichssyntax, die zu offensichtlichen Fehlern bei der Vollständigkeitsprüfung führen kann.Ambiguität in Mustervergleichssyntax

type Thing = 
    | This 
    | That 
    | Other 

let useThing = 
    function 
    | This -> "A" 
    | That -> "A" 
    | That -> "B" // compiler complains 
    | Other -> "B" 

In dem obigen Szenario sagt mir der Compiler hilfreich, dass die zweite Regel nie übereinstimmen wird. Allerdings, wenn ich versucht hätte, den Code ein wenig kompakter zu machen und geschrieben hatte

let useThing = 
    function 
    | This | That -> "A" 
    | That | Other -> "B"  

Ich bekomme keine Hilfe vom Compiler. Ich denke, der Grund ist, dass | This | That ->. "A" keine Abkürzung für | This -> "A" | That -> "A" ist, auch wenn es sehr ähnlich aussieht (und ich habe viele Code-Beispiele gesehen, die es so behandeln). Stattdessen wird das Pipe-Symbol von dem, was ich finden kann, sowohl zum Trennen einzelner Muster als auch als OR-Muster verwendet.

Dies ist kein großes Problem für die meisten DUs, aber ich stieß auf das Problem, wenn ich ein DU mit einer großen Anzahl von Fällen in ein anderes DU mit einer kleinen Anzahl von Fällen abbildete. Mein Versuch, die Shortcut-Syntax zu verwenden, verursachte einen Fehler.

Also meine Fragen sind:

  1. Ist meine Interpretation richtig?
  2. Gibt es eine Umgehungslösung abgesehen von der Auflistung jedes Musters in einer separaten Zeile?

Antwort

8

Ihre Interpretation ist korrekt.

Durch die Aktionen Weglassen zum ersten This und zweiten That Sie ein ODER-Mustern erstellen, da diese in Pattern Matching (F#)

Ich beschrieben ist etwas verwirrend, auch, da die logische ‚oder‘ ist || in F #. Und während es ist einfach, die erste Bar als new alternative und zweite Bar als or in Ihrer Formatierung sehen wird es weniger offensichtlich in

let useThing = 
    function 
    | This 
    | That -> "A" 
    | That 
    | Other -> "B" 

jedoch die Compiler, ob ein ganzes Muster nutzlos sagen können, aber es ein Muster nicht vereinfachen . That | Other hat eine gültige Übereinstimmung und ist daher nicht redundant, wie vom Compiler berücksichtigt.
Sie können sich viel kompliziertere Muster vorstellen, bei denen es nicht klar ist, ob Teile weggelassen werden oder wie sie vereinfacht werden können.

Verwandte Themen