Parece que o código F # geralmente corresponde a padrões em relação aos tipos. Certamente
match opt with
| Some val -> Something(val)
| None -> Different()
parece comum.
Mas, do ponto de vista da OOP, isso se parece muito com o fluxo de controle com base em uma verificação do tipo de tempo de execução, que normalmente seria desaprovada. Para explicar, no POO você provavelmente preferiria usar 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 é certamente mais código. OTOH, parece-me ter vantagens estruturais:
- a extensão para uma nova forma de
Té fácil; - Não preciso me preocupar em encontrar duplicação do fluxo de controle de escolha de rota; e
- A escolha da rota é imutável, no sentido em que, uma vez que tenho uma
Foomão na mão, nunca mais preciso me preocupar comBar.Route()a implementação da
Existem vantagens na correspondência de padrões com tipos que não estou vendo? É considerado idiomático ou é um recurso que não é comumente usado?
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.parece muito dogmático. Às vezes, você deseja separar seus ops da hierarquia: talvez 1) você não possa adicionar um op a uma hierarquia porque não é o proprietário da hierarquia; 2) as classes que você deseja que o op não correspondam à sua hierarquia; 3) você pode adicionar o op à sua hierarquia, mas não quer b / c, não quer desorganizar a API da sua hierarquia com um monte de porcaria que a maioria dos clientes não usa.