2017-01-23 17 views
9
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 ", " 

Trong dòng static member inline PrintArg(_: ArgsPrinter, (x1, x2, x3)) =, khái niệm (x1, x2, x3) mang lại cho tôi những lỗi sau:Làm cách nào để giải quyết lỗi kiểu lạ trong bản đồ đệ quy với các tham số kiểu được giải quyết tĩnh?

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

Bất kỳ ý tưởng phải làm gì đây để làm công việc này?

+1

Điều gì sẽ xảy ra nếu bạn chỉ định rõ ràng các tham số kiểu của 'PrintArg'? –

+1

@FyodorSoikin nó sẽ không hoạt động vì trình phân tích cú pháp F # sẽ từ chối đọc chữ ký của một ràng buộc tĩnh trên một loại danh nghĩa. Điều này sẽ được cho phép trong phiên bản sắp tới của F #. – Gustavo

Trả lời

9

Có vẻ với tôi rằng bạn muốn làm một cái gì đó như thế này:

... 

    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 ", " 

Bạn định nghĩa một hàm tổng quát ở giữa loại bởi vì bạn sẽ sử dụng nó cho hai định nghĩa chồng cuối cùng, mà sẽ trở thành loại của 'quá tải đệ quy'.

Lưu ý rằng kỹ thuật này được sử dụng hiện tại trong FSharpPlus, thực sự là đơn giản hóa kỹ thuật. Cuối cùng lưu ý rằng giải pháp của bạn có vẻ đúng với tôi (mặc dù tiết hơn) nhưng vì lý do nào đó trình biên dịch F # bị nhầm lẫn, tôi không thể giải thích cho bạn tại sao nhưng gặp nhiều tình huống như thế này và tất cả những gì tôi có thể làm là tìm thấy một repro tối thiểu, một workaround và báo cáo cho F # guys. Vẫn còn rất nhiều thứ cần giải quyết trong Constraint Solver.

+0

Tôi nhớ đã đọc một lúc trước rằng kỹ thuật trên không hoạt động trên các phương thức mở rộng nên tôi chưa thử, nhưng tôi đoán đó là sai. Tôi thậm chí đã kiểm tra xem nó có hoạt động trên các bộ dữ liệu lồng nhau hay không. Cảm ơn. –

+4

Bạn chính xác, nó không hoạt động trong các Phương thức mở rộng, nhưng chúng không được biên dịch thành các Phương thức mở rộng nếu chúng nằm trong cùng một tệp. – Gustavo

+0

Tôi có nên báo cáo điều này sau đó hoặc bạn có muốn làm điều đó không? Hay là loại lỗi này đã được báo cáo? –

Các vấn đề liên quan