Обновление FPARSEC: Обновление дискриминационных профсоюзов для удовлетворения новых ограничений равенства/сравнения

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

Вопрос

Итак, по Здравствуйларсерия событий Ious, Я скачал источник FPARSEC и попытался его построить. К сожалению, это не совместимо с новым 1.9.9.9. Я исправил простые проблемы, но есть пара дискриминационных профсоюзов, которые все еще не работают.

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

Вот несколько примеров проблемного DUS:

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 - это правильный способ реализации пользовательского ограничения равенства/сравнения (или, возможно, уникального кортежа Int, чтобы можно было заказать отдельные ветви DU). Но это неудобно для пользователя DU. Теперь строительство DU требует вызова функции, чтобы получить следующую марку.

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

Это было полезно?

Решение

Какой источник вы загрузили для FPARSEC? Я взял последние из FPARSEC Bitbucket Repository, и мне вообще не нужно было вносить какие -либо изменения в источник FPARSEC, чтобы заставить его компилировать в VS 2010 RC.

РЕДАКТИРОВАТЬ: Я забираю это обратно. Я получил ошибки сборки от проектов образцов InterplexyAcc и InterPparSec, но основные проекты FPARSEC и FPARSECCS создаются просто отлично.

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top