Es scheint, als würde F # -Code häufig Muster mit Typen vergleichen. Bestimmt
match opt with
| Some val -> Something(val)
| None -> Different()
scheint üblich zu sein.
Aus OOP-Sicht ähnelt das einem Kontrollfluss auf der Grundlage einer Laufzeit-Typprüfung, die normalerweise verpönt wäre. Um es auszudrücken, würden Sie in OOP wahrscheinlich lieber eine Überladung verwenden:
type T =
abstract member Route : unit -> unit
type Foo() =
interface T with
member this.Route() = printfn "Go left"
type Bar() =
interface T with
member this.Route() = printfn "Go right"
Das ist sicherlich mehr Code. OTOH, meines Erachtens haben strukturelle Vorteile:
- die erweiterung auf eine neue form von
T
ist einfach; - Ich brauche mir keine Sorgen zu machen, ob der Kontrollfluss für die Routenwahl doppelt vorhanden ist. und
- Die Wahl der Route ist in dem Sinne unveränderlich, dass ich
Foo
mich nie mehr umBar.Route()
die Implementierung kümmern muss , wenn ich eine in der Hand habe
Gibt es Vorteile beim Mustervergleich gegenüber Typen, die ich nicht sehe? Wird es als idiomatisch angesehen oder ist es eine Fähigkeit, die nicht allgemein verwendet wird?
But from an OOP perspective, that looks an awful lot like control-flow based on a runtime type check, which would typically be frowned on.
klingt zu dogmatisch. Manchmal möchten Sie Ihre Ops von Ihrer Hierarchie trennen: 1) Sie können einer Hierarchie keine Ops hinzufügen, b / c Sie besitzen die Hierarchie nicht. 2) Die Klassen, für die Sie die Operation durchführen möchten, stimmen nicht mit Ihrer Hierarchie überein. 3) Sie könnten die Option zu Ihrer Hierarchie hinzufügen, möchten aber nicht, dass die API Ihrer Hierarchie mit ein paar Drecksachen überfrachtet wird, die die meisten Clients nicht verwenden.