generics static f# inline

generics - ¿Cómo resolver el error de tipo extraño en un mapa recursivo con parámetros de tipo resueltos estáticamente?



static f# (1)

type CudaInnerExpr<''t> = CudaInnerExpr of expr: string with member t.Expr = t |> fun (CudaInnerExpr expr) -> expr type CudaScalar<''t> = CudaScalar of name: string with member t.Name = t |> fun (CudaScalar name) -> name type CudaAr1D<''t> = CudaAr1D of CudaScalar<int> * name: string with member t.Name = t |> fun (CudaAr1D (_, name)) -> name type CudaAr2D<''t> = CudaAr2D of CudaScalar<int> * CudaScalar<int> * name: string with member t.Name = t |> fun (CudaAr2D (_, _, name)) -> name type ArgsPrinter = ArgsPrinter with static member inline PrintArg(_: ArgsPrinter, t: CudaScalar<float32>) = sprintf "float %s" t.Name static member inline PrintArg(_: ArgsPrinter, t: CudaScalar<int>) = sprintf "int %s" t.Name static member inline PrintArg(_: ArgsPrinter, t: CudaAr1D<float32>) = sprintf "float *%s" t.Name static member inline PrintArg(_: ArgsPrinter, t: CudaAr1D<int>) = sprintf "int *%s" t.Name static member inline PrintArg(_: ArgsPrinter, t: CudaAr2D<float32>) = sprintf "float *%s" t.Name static member inline PrintArg(_: ArgsPrinter, t: CudaAr2D<int>) = sprintf "int *%s" t.Name static member inline PrintArg(_: ArgsPrinter, (x1, x2)) = let inline print_arg x = let inline call (tok : ^T) = ((^T or ^in_) : (static member PrintArg: ArgsPrinter * ^in_ -> string) tok, x) call ArgsPrinter [|print_arg x1;print_arg x2|] |> String.concat ", " static member inline PrintArg(_: ArgsPrinter, (x1, x2, x3)) = let inline print_arg x = let inline call (tok : ^T) = ((^T or ^in_) : (static member PrintArg: ArgsPrinter * ^in_ -> string) tok, x) call ArgsPrinter [|print_arg x1;print_arg x2;print_arg x3|] |> String.concat ", "

En la línea static member inline PrintArg(_: ArgsPrinter, (x1, x2, x3)) = , la expresión (x1, x2, x3) me da el siguiente error:

Script1.fsx(26,52): error FS0001: This expression was expected to have type ''in_ but here has type ''a * ''b * ''c

¿Alguna idea de qué hacer aquí para que esto funcione?


Me parece que quieres hacer algo como esto:

... static member inline PrintArg(_: ArgsPrinter, t: CudaAr2D<float32>) = sprintf "float *%s" t.Name static member inline PrintArg(_: ArgsPrinter, t: CudaAr2D<int>) = sprintf "int *%s" t.Name let inline print_arg x = let inline call (tok : ^T) = ((^T or ^in_) : (static member PrintArg: ArgsPrinter * ^in_ -> string) tok, x) call ArgsPrinter type ArgsPrinter with static member inline PrintArg(_: ArgsPrinter, (x1, x2)) = [|print_arg x1;print_arg x2|] |> String.concat ", " static member inline PrintArg(_: ArgsPrinter, (x1, x2, x3)) = [|print_arg x1;print_arg x2;print_arg x3|] |> String.concat ", "

Usted define la función genérica en el medio del tipo porque la usará para las dos últimas sobrecargas, que se convertirán en una especie de ''sobrecarga recursiva''.

Tenga en cuenta que esta es la técnica utilizada actualmente en FSharpPlus , en realidad una simplificación de la técnica.

Finalmente, tenga en cuenta que su solución también parece correcta para mí (aunque más detallada) pero por alguna razón el compilador de F # se confunde, no puedo explicarle por qué, pero he conocido muchas situaciones como esta y todo lo que puedo hacer es encontrar una reproducción mínima , una solución e informarlo a los chicos de F #. Todavía hay muchas cosas por resolver en el Solucionador de Restricciones.