Parece que el código F # a menudo coincide con patrones contra tipos. Ciertamente
match opt with
| Some val -> Something(val)
| None -> Different()
Parece común.
Pero desde una perspectiva OOP, eso se parece mucho al flujo de control basado en una verificación de tipo de tiempo de ejecución, que generalmente estaría mal visto. Para explicarlo, en OOP probablemente preferirías usar la sobrecarga:
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"
Este es ciertamente más código. OTOH, me parece que mi OOP-y tiene ventajas estructurales:
- la extensión a una nueva forma de
T
es fácil; - No tengo que preocuparme por encontrar la duplicación del flujo de control de elección de ruta; y
- la elección de la ruta es inmutable en el sentido de que una vez que tengo una
Foo
en la mano, nunca necesito preocuparme porBar.Route()
la implementación
¿Existen ventajas para la coincidencia de patrones con los tipos que no veo? ¿Se considera idiomático o es una capacidad que no se usa comúnmente?
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.
suena demasiado dogmático. A veces, desea separar sus operaciones de su jerarquía: quizás 1) no puede agregar una operación a una jerarquía b / c que no posee la jerarquía; 2) las clases que desea tener la operación no coinciden con su jerarquía; 3) puede agregar la operación a su jerarquía, pero no quiere b / c no quiere saturar la API de su jerarquía con un montón de basura que la mayoría de los clientes no usan.