Aggiornamento FParsec: upgrade sindacati discriminati per soddisfare le nuove parità / vincoli di confronto

StackOverflow https://stackoverflow.com/questions/2290103

Domanda

Quindi, da un hi lar serie di eventi pagherò , ho scaricato la fonte FParsec e ha cercato di costruirlo. Purtroppo, non è compatibile con il nuovo 1.9.9.9. Ho sistemato i problemi facili, ma ci sono un paio di sindacati discriminati che ancora non funzionano.

In particolare, post di Don Syme spiega che i sindacati discriminati contenenti elementi di tipo obj o -> non ottengono automaticamente vincoli di uguaglianza o di confronto, dal momento che gli oggetti non supportano il confronto e le funzioni non supportano l'uguaglianza sia . (Non è chiaro se l'uguaglianza generato automaticamente / confronto è stato buggy prima, ma il codice non sarà nemmeno la compilazione ora che non sono più generati.)

Ecco alcuni esempi di tossicodipendenti problematici:

type PrecedenceParserOp<'a,'u'> =
     | PrefixOp of string * Parser<unit,'u> * int * bool * ('a -> 'a)
     | others ...

type ErrorMessage =
     | ...
     | OtherError of obj
     | ...

Ecco l'incriminato utilizza:

member t.RemoveOperator (op: PrecedenceParserOp<'a, 'u>) =
    // some code ...
    if top.OriginalOp <> op then false // requires equality constraint
    // etc etc ...

o, per il vincolo di confronto

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 ...

Per quanto posso dire, la soluzione di Don di codifica ogni istanza con un int unico è il modo giusto per implementare un vincolo di uguaglianza custom / confronto (o forse un int tupla univoco in modo che i rami individuali del DU possono essere ordinati) . Ma questo è scomodo per l'utente del DU. Ora, la costruzione del DU richiede chiamare una funzione per ottenere il prossimo francobollo.

C'è qualche modo per nascondere la tag-ottenere e presentare gli stessi costruttori per gli utenti della biblioteca? Cioè, per cambiare l'implementazione senza cambiare l'interfaccia? Questo è particolarmente importante perché sembra (da quello che ho capito del codice) che PrecedenceParserOp è un tipo di pubblico.

È stato utile?

Soluzione

Cosa fonte hai scaricare FParsec? Ho afferrato le ultime dal FParsec BitBucket repository , e non ho dovuto apportare modifiche al tutto alla fonte FParsec per farlo compilare in VS 2010 RC.

Edit: mi correggo. Ho avuto errori di generazione dei progetti di esempio InterpLexYacc e InterpFParsec, ma i progetti di base FParsec e FParsecCS costruire bene.

Altri suggerimenti

Una cosa che potreste fare è aggiungere attributi [<CustomEquality>] e [<CustomComparison>] e definire una propria implementazione .Equals override e IComparable. Naturalmente, ciò richiederebbe di gestire i componenti obj e _ -> _ se stessi in un modo appropriato, che può o non può essere possibile. Se è possibile controllare ciò che viene passato al costruttore OtherError, si dovrebbe essere in grado di fare questo lavoro per la ErrorMessage dal downcasting il obj a un tipo che è essa stessa strutturalmente comparabile. Tuttavia, il caso PrecendenceParserOp è un po 'più complicato -. Potrebbe essere in grado di cavarsela con l'utilizzo di uguaglianza di riferimento sui componenti di funzione finché non hai bisogno di confronto e

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top