2017-01-23 4 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 ", " 

、表現(x1, x2, x3)は私に次のエラーを与える:静的に解決された型パラメータを持つ再帰的なマップで奇妙な型のエラーを解決するには?ライン<code>static member inline PrintArg(_: ArgsPrinter, (x1, x2, x3)) =</code>で

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

この作業を行うためにここに何をするか任意のアイデアを?

+1

'PrintArg'の型パラメータを明示的に指定するとどうなりますか? –

+1

@FyodorSoikin F#パーサは公称型の静的な制約の署名の読み込みを拒否するため、動作しません。これはF#の次のバージョンで許可されます。 – Gustavo

答えて

9

それはあなたがこのような何かをしたいと私になります

... 

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

あなたが親切になり、最後の2つのオーバーロード、それを使用しますので、あなたがタイプの真ん中に汎用関数を定義します「再帰的過負荷」の

このテクニックは現在FSharpPlusで使用されていますが、実際はこのテクニックが単純化されています。

最後に、あなたの解決策も私には正しいように思えますが(もっと冗長ですが)何らかの理由でF#コンパイラが混乱してしまいます。なぜならこの理由を説明できません。回避策を見つけてF#の人に報告してください。制約ソルバーにはまだ解決すべきことがたくさんあります。

+0

上記のテクニックは拡張メソッドでは機能しないので、私はそれを試していないことを少し前に覚えていますが、間違っていたと思います。私はそれがネストされたタプルで動作するかどうかをチェックしていました。ありがとう。 –

+4

正しいですが、拡張メソッドでは機能しませんが、同じファイルにある場合は拡張メソッドとしてコンパイルされません。 – Gustavo

+0

これを報告したいのですか、それともしたいですか?あるいはすでにこの種のバグは報告されていますか? –

関連する問題