Mise à niveau FParsec: mise à niveau des syndicats discriminés pour répondre aux nouvelles contraintes de l'égalité / comparaison
-
21-09-2019 - |
Question
Alors, par un salut lar série IOU d'événements , j'ai téléchargé la source FParsec et a essayé de le construire. Malheureusement, ce n'est pas compatible avec le nouveau 1.9.9.9. Je fixe les problèmes faciles, mais il y a deux syndicats discriminés qui ne fonctionnent toujours pas.
Plus précisément, poste de Don Syme explique que les syndicats discriminés contenant des objets de type obj
ou ->
ne reçoivent pas automatiquement l'égalité ou les contraintes de comparaison, car les objets ne supportent pas la comparaison et les fonctions ne prennent pas en charge soit l'égalité . (On ne sait pas si le produit automatiquement l'égalité / comparaison était bogué avant, mais le code compilera même pas maintenant qu'ils sont pas générés plus.)
Voici quelques exemples de la problématique DDVP:
type PrecedenceParserOp<'a,'u'> =
| PrefixOp of string * Parser<unit,'u> * int * bool * ('a -> 'a)
| others ...
type ErrorMessage =
| ...
| OtherError of obj
| ...
Voici l'infraction utilise:
member t.RemoveOperator (op: PrecedenceParserOp<'a, 'u>) =
// some code ...
if top.OriginalOp <> op then false // requires equality constraint
// etc etc ...
ou, pour la contrainte de comparaison
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 ...
En ce que je peux dire, la solution de Don de marquage chaque instance avec un int unique est la bonne façon de mettre en œuvre une contrainte égalité personnalisée / comparaison (ou peut-être un tuple int unique afin que les branches individuelles de l'UA peuvent être commandés) . Mais cela est gênant pour l'utilisateur du DU. Maintenant, la construction de l'UA exige d'appeler une fonction pour obtenir le prochain timbre.
Y at-il un moyen de cacher l'étiquette-faire et présenter les mêmes constructeurs pour les utilisateurs de la bibliothèque? Autrement dit, de changer la mise en œuvre sans changer l'interface? Ceci est particulièrement important car il semble (d'après ce que je comprends du code) que PrecedenceParserOp
est un type public.
La solution
Quelle source avez-vous télécharger FParsec? Je saisis les dernières nouvelles de la FParsec BitBucket dépôt , et je ne devais pas apporter des modifications à tous à la source FParsec pour le compiler dans VS 2010 RC.
Edit: Je retire ce que. Je ne reçois des erreurs de compilation des exemples de projets et InterpLexYacc InterpFParsec, mais les principaux FParsec et les projets FParsecCS construire très bien.
Autres conseils
Une chose que vous pouvez faire est d'ajouter des attributs de [<CustomEquality>]
et [<CustomComparison>]
et définir votre propre implémentation de remplacement et .Equals
IComparable
. Bien sûr, cela vous obligera à gérer les composants obj
et _ -> _
-vous d'une manière appropriée, ce qui peut ou peut ne pas être possible. Si vous pouvez contrôler ce qui est passé dans le constructeur de OtherError
, vous devez être en mesure de faire ce travail pour le type de ErrorMessage
par le obj
à coulée en descente un type qui est lui-même une structure comparable. Cependant, le cas de PrecendenceParserOp
est un peu plus délicat -. Vous pourriez être en mesure d'obtenir par l'utilisation de l'égalité de référence sur les composants de fonction aussi longtemps que vous n'avez pas besoin de comparaison et