Diskriminierte Gewerkschaften funktionieren am besten, wenn zwischen den Fällen keine semantische Überschneidung besteht.
In Ihrem Beispiel enthält jeder Fall dieselbe Komponente mit derselben Bedeutung, wobei string
"den Namen des Tieres" angibt. Aber das ist eine semantische Überschneidung! Die diskriminierende Gewerkschaft wird dich dann zwingen, Unterscheidungen zu treffen, die du nicht willst: Du willst nicht gezwungen werden, zwischen dem "Namen eines Schweins" und dem "Namen einer Kuh" zu unterscheiden. ; Sie wollen nur an "den Namen eines Tieres" denken.
Machen wir einen Typ, der besser passt:
%Vor% Bei diesem Typ ist das Herausfiltern von nicht Pig
s ein Einzeiler:
Wenn nicht jedes Tier einen Namen hat, verwenden Sie eine Option:
%Vor% Sie würden eine diskriminierte Vereinigung für Ihre Tiere verwenden, wenn Sie wüssten, dass beispielsweise jeder Pig
einen Namen hat, aber kein Fish
: diese Fälle haben keine Überlappung.
Sie können die Funktion filterAnimals
ändern, um ein partielles aktives Muster als Eingabe zu verwenden:
Dann können Sie ein aktives Teilmuster für Schweine definieren:
%Vor%Und Sie können die Funktion wie folgt aufrufen (FSI-Beispiel):
%Vor%Tatsächlich können Sie das teilweise aktive Muster wie folgt reduzieren:
%Vor%Und es stellt sich heraus, dass Sie sie sogar inline einfügen können:
%Vor% Nur aus Gründen der Vollständigkeit listet ich diese Lösung auf.
Wenn Sie Ihre Eingabe zitieren , können Sie dies nachvollziehen über die Namen der Tags:
Das ist zugegebenermaßen ziemlich ausführlich, und es würde noch mehr werden, wenn Sie eine Liste anstatt eines einzelnen Wertes zitieren möchten.
Eine etwas andere Version, in der wir nur den Tiertyp angeben, würde es Ihnen erlauben, Listen von Tieren zu filtern, so wie Sie es brauchen (zum Preis eines fraglichen Vergleichs von Strings):
%Vor%Die letztere Version ist nicht wirklich besser, als den Tag-Namen als String zu übergeben.
Nein, es ist nicht möglich, nur das Tag zu übergeben, um das Tag und die Zeichenfolge, die Sie definieren können, getrennt behandeln zu können:
%Vor% Alternativ können Sie auch nur ein Tupel von AnimalType * string
AKTUALISIEREN
In Bezug auf Ihre Frage in den Kommentaren, was passiert, wenn die Struktur nicht immer die gleiche ist, gibt es einen Trick, den Sie verwenden können: Sie können den Typ von zwei diskriminierten Unions vergleichen, da jedes Tag in eine andere Unterklasse kompiliert wird / p> %Vor%
Aber bevor Sie diesen Weg gehen, sollten Sie überlegen, ob Sie Ihr Problem wirklich so modellieren müssen.
Auch wenn Sie sich für diese Struktur entscheiden, würde ich lieber die eingebaute Filterfunktion verwenden, siehe die von @polkduran vorgeschlagene Lösung.
Dies beantwortet Ihre Frage nicht direkt, sondern schlägt einen alternativen Weg vor, um das zu erreichen, was Sie wollen.
Sie könnten Ihre Liste mit der vorhandenen Funktion hoher Ordnung List.filter
und dem Mustervergleich filtern:
Ich denke, das ist ein idiomatischer Ansatz: Sie filtern Ihre Liste mit einem Muster, in diesem Fall filtern Sie Ihre Tiere und behalten nur diejenigen, die das Muster Pig(_)
erfüllen.
Tags und Links f# pattern-matching discriminated-union