Схоже, що F # код часто узгоджується з типом. Звичайно
match opt with
| Some val -> Something(val)
| None -> Different()
здається загальним.
Але з точки зору OOP, це виглядає надзвичайно багато, як контрольний потік на основі перевірки типу виконання, який, як правило, нахмуриться. Щоб прописати це, в OOP ви, мабуть, віддасте перевагу використовувати перевантаження:
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"
Це, звичайно, більше коду. ОТОХ, на мій погляд, OOP-y має структурні переваги:
- поширення на нову форму
T
легко; - Мені не потрібно турбуватися про те, щоб знайти дублювання керуючого потоку вибору маршруту; і
- Вибір маршруту незмінний в тому сенсі, що коли я маю
Foo
руку, мені ніколи не потрібно хвилюватися про їїBar.Route()
реалізацію
Чи є переваги в узгодженні шаблонів щодо типів, які я не бачу? Це вважається ідіоматичним чи це здатність, яка не використовується зазвичай?
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.
- звучить занадто догматично. Іноді, ви хочете відокремити свій ops від своєї ієрархії: можливо, 1) ви не можете додати оп до ієрархії b / c, у вас немає ієрархії; 2) класи, які ви хочете мати, не відповідають вашій ієрархії; 3) ви можете додати оп у свою ієрархію, але не хочете перебирати / не хочете переповнювати API вашої ієрархії безліччю лайна, якою більшість клієнтів не користується.