Atualizando o FPARSEC: Atualizar sindicatos discriminados para satisfazer as novas restrições de igualdade/comparação
-
21-09-2019 - |
Pergunta
Então, por um OiLarsérie de eventos IOUS, Baixei a fonte do FPARSEC e tentei construí -la. Infelizmente, não é compatível com o novo 1.9.9.9. Corrigi os problemas fáceis, mas existem alguns sindicatos discriminados que ainda não funcionam.
Especificamente, Postagem de Don Syme explica que os sindicatos discriminados contendo itens do tipo obj
ou ->
Não obtenha automaticamente restrições de igualdade ou comparação, pois os objetos não suportam comparação e as funções também não suportam igualdade. (Não está claro se a igualdade/comparação gerada automaticamente era antes, mas o código nem sequer compilará agora que não são mais gerados.)
Aqui estão alguns exemplos das DUs problemáticas:
type PrecedenceParserOp<'a,'u'> =
| PrefixOp of string * Parser<unit,'u> * int * bool * ('a -> 'a)
| others ...
type ErrorMessage =
| ...
| OtherError of obj
| ...
Aqui estão os usos ofensivos:
member t.RemoveOperator (op: PrecedenceParserOp<'a, 'u>) =
// some code ...
if top.OriginalOp <> op then false // requires equality constraint
// etc etc ...
ou, para a restrição de comparação
let rec printMessages (pos: Pos) (msgs: ErrorMessage list) ind =
// other code ...
for msg in Set.ofList msgs do // iterate over ordered unique messages
// etc etc ...
Até onde posso dizer, a solução de Don de marcar cada instância com uma INT exclusiva é a maneira certa de implementar uma restrição de igualdade/comparação personalizada (ou talvez uma completa exclusiva para que ramificações individuais do DU possam ser solicitadas). Mas isso é inconveniente para o usuário do DU. Agora, a construção do DU exige chamar uma função para obter o próximo carimbo.
Existe alguma maneira de ocultar a etiqueta e apresentar os mesmos construtores para os usuários da biblioteca? Isto é, para alterar a implementação sem alterar a interface? Isso é especialmente importante porque parece (pelo que eu entendo do código) que PrecedenceParserOp
é do tipo público.
Solução
Qual fonte você baixou para o FPARSEC? Eu peguei o mais recente do FPARSEC Repositório de Bitbucket, e eu não precisei fazer nenhuma alteração na fonte do FPARSEC para compilar no VS 2010 RC.
EDIT: Eu pego isso de volta. Recebi erros de construção dos projetos de amostra Interplexyacc e InterpFPARSEC, mas os projetos principais FPARSEC e FPARSECCS se formam muito bem.
Outras dicas
Uma coisa que você poderia fazer é adicionar [<CustomEquality>]
e [<CustomComparison>]
atributos e defina o seu próprio .Equals
substituir e IComparable
implementação. Claro, isso exigiria que você lide com o obj
e _ -> _
Componentes de uma maneira apropriada, o que pode ou não ser possível. Se você pode controlar o que está sendo passado para o OtherError
construtor, você deve ser capaz de fazer isso funcionar para o ErrorMessage
digite abatando o obj
a um tipo que é estruturalmente comparável. No entanto, o PrecendenceParserOp
O caso é um pouco mais complicado - você pode obter usando a igualdade de referência nos componentes da função, desde que não precise de comparação também.