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.