Собрать значения аргументов TypeProvider ProvidedMethod в списке - PullRequest
0 голосов
/ 27 декабря 2018

Вот упрощенный фрагмент метода Provided, который принимает переменное число аргументов, в данном случае 3

ProvidedMethod(methodName = "GetContext", 
               parameters = [ for i in [ 1..3 ] do
                                  yield ProvidedParameter("Param" + string i, typeof<string>) ], 
               IsStaticMethod = true, returnType = typeof<string>, 
               InvokeCode = (fun args -> 
                   <@@ 
                       let dim1 : string = %%args.[0] : string
                       let dim2 : string = %%args.[1] : string
                       let dim3 : string = %%args.[2] : string
                 //    let dims = [for %%arg in args do yield (arg : string) ]// [1] error below
                 //    let dims = [for arg in args do yield (%%arg : string) ]// [2] error below
                       let dims = [ dim1; dim2; dim3 ] //this works
                       String.Join("--", dims)
                   @@>))

Я хочу собрать все аргументы в одном списке.

ЧтоЯ пробовал и не работал, комментируется в цитате.

[1]: [FS0010] Unexpected prefix operator in expression
     [FS0594] Identifier expected

[2]: [FS0446] The variable 'arg' is bound in a quotation but is used as part of a spliced expression. This is not permitted since it may escape its scope.

Ответы [ 2 ]

0 голосов
/ 27 декабря 2018

Такое решение также работало на основе ответа, предложенного в комментариях: F # Разработка типа провайдера: При предоставлении метода, как получить доступ к параметрам переменного числа и типа?

ProvidedMethod(methodName = "GetContext", 
           parameters = [ for i in [ 1..3 ] do
                              yield ProvidedParameter("Param" + string i, typeof<string>) ], 
           IsStaticMethod = true, returnType = typeof<string>, 
           InvokeCode = (fun args -> 
               let dims = List.fold ( fun state e -> <@@ (%%string)::%%state @@>) <@@ []:List<string> @@> args
               <@@ 
                   String.Join("--", dims)
               @@>))
0 голосов
/ 27 декабря 2018

Взлом вашего решения следующим образом на самом деле компилирует

InvokeCode = (fun args -> 
    let dims: string[] = Array.zeroCreate args.Length
    let mutable i = 0
    let inc () = i <- i + 1
    <@@
        while i < args.Length do
            dims.[i] <- %%args.[i]
            inc ()
        String.Join("--", dims)
    @@>

Но я подозреваю, что вы скорее хотите преобразовать Quotations.Expr[] фигуры [|Value ("a"); Value ("b"); Value ("c")|] в один Quotations.Expr.

Вы можете использовать шаблоны в Microsoft.FSharp.Quotations.Patterns для извлечения материала из выражений следующим образом

InvokeCode = (fun args -> 
    let dims =
        args
        |> Array.choose (function | Value(value, _) -> value |> string |> Some | _ -> None)
        |> fun arr -> String.Join("--", arr)
    <@@ dims @@>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...