F # padrão ativo como membro não-estático
-
11-09-2019 - |
Pergunta
Eu não tenho certeza se os padrões de ativos de membro público não-estático são permitidos, mas você pode defini-los sem o compilador reclamando. Se eles são permitidos o que é a sintaxe para fazer a comparação com um? O compilador está me dando uma incompatibilidade tipo para Foo em FooBar2.doSomething. Esperando um 'a -> Choice<'b,'c>
dada 'a -> 'd -> Choice<unit,unit>
// No error in this class, static works great
type FooBar() =
static member (|Foo|Bar|) (x, y) =
match x = y with
| true -> Foo
| false -> Bar
member x.doSomething y =
match x, y with
| Foo -> ()
| Bar -> ()
type FooBar2() =
member x.(|Foo|Bar|) y =
match x = y with
| true -> Foo
| false -> Bar
// compiler error on "Foo"
member x.doSomething y =
match y with
| Foo -> ()
| Bar -> ()
Solução
padrões de ativos não deve ser usado como membros. O fato de que estes compilação em tudo é um erro compilador que nós vamos corrigir (graças para o relatório :)). Use local ou "deixe"-bound módulo é definir um padrão ativo.
Outras dicas
Não estou surpreso que isso não funciona, e eu não posso ver uma interpretação semântica natural para os padrões de ativos de instância. Como você sabe qual instância para usar quando você ver o padrão Foo
? você poderia ter diferentes instâncias para os casos Foo
e Bar
(e, portanto, uma correspondência padrão incompleto)? Não parece ser uma elegante solução às questões aqui. Para ser honesto, eu estou surpreso que mesmo as obras caso estático, e eu não vejo nada na especificação abordando a definição de padrões de ativos como membros de qualquer tipo.
reconhecedores membros parecem estar fora desde a versão 1.9.9.9. mesmo para membros estáticos. Eu acho que é uma vergonha, porque permitiu a sobrecarga reconhecedor. Eu poderia ter um reconhecedor 'Nome' para Tipo, MemberInfo etc. Agora eu preciso ter um 'type_name'. 'MEMBER_NAME' etc., para evitar conflitos de nomes. Apenas 'Nome' era mais agradável.