Как вызвать функцию из цитаты вызова в поставщике типов?

У меня есть поставщик типов, который выдает ошибку «Несоответствие типов при вставке выражения в кавычки».

Я извлек приведенный ниже код, чтобы воспроизвести проблему в меньшем контексте.

let f (s : string) : string = s //some dummy implementation

let t = ProvidedTypeDefinition(asm, ns, "Root", Some typeof<obj>)
let ctor = ProvidedConstructor(parameters = [],
                               InvokeCode = (fun args -> <@@ "root" :> obj @@>)) :> MemberInfo

let prop = ProvidedProperty(propertyName = "SomeProperty",
                            parameters = [],
                            propertyType = typeof<string>,
                            GetterCode = (fun args -> <@@ f %%(args.[0]) @@>)) :> MemberInfo

do  t.AddMembers [ctor; prop]
    t.SetBaseType typeof<obj>

... и когда я использую поставщик типа, например

let root = Provided.Root()

let a = root.SomeProperty

Я получаю сообщение об ошибке:

Ошибка: поставщик типа typeproviders.providerpoc + MyProvider сообщил об ошибке в контексте предоставленного типа typeproviders.providerpoc.Provided.Root, члена get_Menu.

Ошибка: несоответствие типов при вставке выражения в литерал цитаты.

Тип вставляемого дерева выражения не соответствует типу, ожидаемому операцией соединения.

Ожидается System.Object, но получен тип System.String.

Рассмотрите возможность аннотирования типа с помощью ожидаемого типа выражения, например, (%% x: string) или (% x: string) .. Имя параметра: ReceiveType.

Как я могу написать цитату, чтобы иметь возможность вызывать функцию внутри цитаты?

Спасибо!


person vidi    schedule 03.02.2017    source источник
comment
Вы пробовали добавлять примечания к ожидаемому типу, как сообщает вам сообщение об ошибке?   -  person Fyodor Soikin    schedule 03.02.2017
comment
@FyodorSoikin - сообщение немного вводит в заблуждение, потому что string его часть является просто примером, не связанным с фактическим несоответствием типов, и представляет ожидаемый тип, а не полученный тип. Таким образом, вам действительно нужно будет использовать %%(args.[0] : obj), но это ничего не исправит, поскольку f ожидает строку. Ответ Томаса показывает, как это исправить.   -  person kvb    schedule 03.02.2017


Ответы (1)


Сообщение об ошибке говорит о том, что вы помещаете цитируемое выражение типа obj в место, где ожидается цитируемое выражение типа string.

Я подозреваю, что это происходит при создании GetterCode в предоставленном свойстве:

GetterCode = (fun args -> <@@ f %%(args.[0]) @@>)

Здесь args - это массив выражений в кавычках, где каждое выражение имеет тип obj, но функция f ожидает строку, поэтому цитата, заполняющая дыру с использованием %%, должна иметь тип string

Добавление преобразования типа, которое превратит obj в string, должно помочь:

GetterCode = (fun args -> <@@ f (unbox<string> (%%(args.[0]))) @@>)
person Tomas Petricek    schedule 03.02.2017