2

Я хотел бы знать, можно ли создать DU в f # с помощью Reflection.emit (или что-нибудь еще там) или даже добавить новые случаи в уже определенный DU.Использование Reflection.Emit для генерации дискриминационных объединений

Я смотрел веб-сайт msdn, и я узнал, что все, что я могу сделать, - это получить профсоюзные дела или создать профсоюзные дела. Либо используя FSharpValue.MakeUnion или используя предложения с Expr.NewUnionCase, чтобы создать их.

Проблема, связанная с использованием этих методов, заключается в том, как я мог бы связать их таким образом, чтобы дела объединения, которые я сделал, принадлежали одному и тому же DU? Возможно, это не право на решение этой проблемы. В таком случае, как я буду генерировать DU динамически?

P.S: Цель будет генерировать Дус внутри поставщика Типа. Это означало бы, если я не ошибаюсь, что при компиляции в DLL-файл я мог бы получить доступ к DU, сгенерированному в файле сценария TypeProvider. Таким образом, это означает, что я смогу применить сопоставление шаблонов по экземпляру DU, а также получить безопасность типов, предоставляемую DU (полнота всех случаев в сопоставлении с образцом, например).

ответ

6

Я бы посмотрел на F# Compiler Services, чтобы генерировать дискриминационные объединения динамически. В принципе, вы полагаетесь на компилятор F # для генерации требуемых типов. Мое ограниченное понимание заключается в том, что как записи, так и дискриминированные союзы требуют каких-то метаданных сборки, кроме того, что компилятор F # распознает их как таковые. Если вы поехали по маршруту Reflection.Emit, вам нужно убедиться, что любые сгенерированные сборки имеют эти метаданные, если это возможно через этот API.

Поставщики типов не могут выставлять записи и дискриминационные объединения прямо сейчас с F # 4.0. Есть a F# Uservoice suggestion for it; но он, вероятно, будет некоторое время, прежде чем он превратит его в язык. То, что я хотел бы сделать, это создать соединение с вышеперечисленными службами компилятора и добавить элемент «Матч» с совпадением шаблона внутри него. Он не будет официальным «DU», когда он пройдет через механизм провайдера, но все равно будет работать.

+0

спасибо, что посмотрели. В настоящее время я пытаюсь сделать то, что вы предложили, но я не совсем понимаю, как я могу сгенерировать любой DU, используя службу компилятора F #. Единственное, что я нашел, это следующий Compiler.SourceCodeServices.FSharpUnionCase, но, по моему мнению, вы можете получить информацию только о существующих случаях объединения. Я пытаюсь, но я не вижу, как я мог бы использовать службу компилятора для создания любого типа. – Leleutch

+0

См. Раздел «Хостинг F # компилятора» в документации. Вы даете ему код, и он создает либо нормальную, либо динамическую сборку в зависимости от того, как вы ее используете. Все, что вам нужно сделать, это дать ему код, который представляет ваш запрещенный союз. – akara

+0

Ох, я вижу, так что это выглядит как довольно красивая печать в действии. И, конечно же, это также означает, что если я уже определил другой тип (например, type1 .. typeN), я могу добавить их в код DU и при компиляции DU действительно будет привязан к ним. Теперь я понимаю. благодаря – Leleutch