Обновление FParsec: обновить разграниченные объединения, чтобы удовлетворить новые ограничения равенства / сравнения - PullRequest
1 голос
/ 18 февраля 2010

Итак, по серии hi lar ious я скачал исходный код FParsec и попытался его построить. К сожалению, он не совместим с новым 1.9.9.9. Я исправил простые проблемы, но есть пара союзов, которые все еще не работают.

В частности, Пост Дона Сайма объясняет, что различимые союзы, содержащие элементы типа obj или ->, не получают автоматически равенство или ограничения сравнения, поскольку объекты не поддерживают сравнение, а функции don ' не поддерживает равенство либо. (Непонятно, была ли ошибка в сгенерированном автоматически равенстве / сравнении раньше, но код даже не скомпилируется, поскольку они больше не генерируются.)

Вот несколько примеров проблемных DU:

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

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

Вот оскорбительное использование:

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

или, для ограничения сравнения

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

Насколько я могу судить, решение Дона пометить каждый экземпляр уникальным int - это правильный путь для реализации пользовательского ограничения равенства / сравнения (или, возможно, уникального кортежа, позволяющего упорядочить отдельные ветви DU). , Но это неудобно для пользователя DU. Теперь построение DU требует вызова функции для получения следующего штампа.

Есть ли способ скрыть получение тегов и представить одинаковые конструкторы пользователям библиотеки? То есть изменить реализацию без изменения интерфейса? Это особенно важно, поскольку кажется (из того, что я понимаю в коде), что PrecedenceParserOp является публичным типом.

Ответы [ 2 ]

2 голосов
/ 18 февраля 2010

Какой источник вы скачали для FParsec? Я взял последнюю версию из репозитория FParsec BitBucket , и мне не пришлось вносить какие-либо изменения в исходный код FParsec для его компиляции в VS 2010 RC.

Редактировать: Я забираю это обратно. Я получал ошибки сборки из примеров проектов InterpLexYacc и InterpFParsec, но основные проекты FParsec и FParsecCS собирались просто отлично.

1 голос
/ 18 февраля 2010

Одна вещь, которую вы можете сделать, это добавить атрибуты [<CustomEquality>] и [<CustomComparison>] и определить собственную .Equals переопределение и IComparable реализацию.Конечно, для этого потребуется, чтобы вы самостоятельно обрабатывали компоненты obj и _ -> _ соответствующим образом, что может быть или не быть возможным.Если вы можете контролировать то, что передается в конструктор OtherError, вы должны иметь возможность выполнить эту работу для типа ErrorMessage, понижая obj до типа, который сам по себе структурно сопоставим.Тем не менее, случай PrecendenceParserOp немного сложнее - вы можете обойтись при использовании равенства ссылок на компоненты функций, если вам также не нужно сравнение.

...