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 ", "
In the line static member inline PrintArg(_: ArgsPrinter, (x1, x2, x3)) =
, the expression (x1, x2, x3)
gives me the following error:
Script1.fsx(26,52): error FS0001: This expression was expected to have type
'in_
but here has type
'a * 'b * 'c
Any idea what to do here to make this work?
It looks to me that you want to do something like this:
...
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 ", "
You define the generic function in the middle of the type because you will use it for the last two overloads, which will become kind of 'recursive overloads'.
Note that this the technique used currently in FSharpPlus, actually a simplification of the technique.
Finally note that your solution seems also correct to me (although more verbose) but for some reason the F# compiler get confused, I can't explain you why but have met many situations like this one and all I can do is find a minimal repro, a workaround and report it to the F# guys. There's still lot of things to be solved in the Constraint Solver.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With