私はこれについて2つのバリエーションを試しましたが、どちらも同じ問題を抱えています。静的に解決された型パラメータを持つ再帰的なマップで奇妙な型のエラーを解決するには? (pt 2)
type CudaScalar<'t> = CudaScalar of name: string with
member t.Name = t |> fun (CudaScalar name) -> name
type TypePrinter<'t>() = class end
let inline print_type x =
((^T or ^in_) : (static member PrintType: TypePrinter< ^in_> -> string) x)
type TypePrinter with
static member inline PrintType(_: TypePrinter<float32>) = "float32"
static member inline PrintType(_: TypePrinter<int>) = "int"
type ArgsPrinter = ArgsPrinter
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, t: CudaScalar< ^t>) =
[|print_type (TypePrinter< ^t>()); t.Name|] |> String.concat " "
type CudaScalar<'t> = CudaScalar of name: string with
member t.Name = t |> fun (CudaScalar name) -> name
type TypePrinter = TypePrinter
let inline print_type x =
let call (tok: ^T) = ((^T or ^in_) : (static member PrintType: TypePrinter * ^in_ -> string) tok, x)
call TypePrinter
type TypePrinter with
static member inline PrintType(_: TypePrinter,_: float32) = "float32"
static member inline PrintType(_: TypePrinter,_ : int) = "int"
type ArgsPrinter = ArgsPrinter
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, t: CudaScalar< ^t>) =
[|print_type Unchecked.defaultof< ^t>; t.Name|] |> String.concat " "
最初に私はprevious questionのように正確に同じエラーを得たが、私は削除した後:
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 ", "
私は最後の3行にこれを得た(両方の変形のために):
Script1.fsx(16,34): error FS0193: Type constraint mismatch. The type
'in_
is not compatible with type
FSI_0002.CudaScalar<'a>
The type ''in_' does not match the type 'FSI_0002.CudaScalar<'a>'
これは私にとって驚いたrエラーはIntellisenseでは表示されませんが、F#Interactiveで実行しようとすると表示されます。ここで何をやり直すべきかわかりません。私はタイプシステムを少し乱用するかもしれませんが、私はタグのないスタイルでこのCudaコンパイラを完成させることに決めました。後の段階で型情報を伝播するために、このようにする必要があります。
編集:グスタボの修正はうまくいきますが、もう少し進むともう一度壊れます。
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 TypePrinter<'t>() = class end
let inline print_type x =
((^T or ^in_) : (static member PrintType: TypePrinter< ^in_> -> string) x)
type TypePrinter with
static member inline PrintType(_: TypePrinter<float32>) = "float32"
static member inline PrintType(_: TypePrinter<int>) = "int"
type ArgsPrinter = ArgsPrinter with
static member inline PrintArg(_: ArgsPrinter, t: CudaScalar< ^t>) =
[|print_type (TypePrinter< ^t>()); t.Name|] |> String.concat " "
static member inline PrintArg(_: ArgsPrinter, t: CudaAr1D< ^t>) =
[|print_type (TypePrinter< ^t>()); "*"; t.Name|] |> String.concat " "
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行で、ptと同じエラーが表示されます。これの1。私がここでやろうとしているのは、埋め込まれたCuda DSLの一部です。私がDUを使うのではなく、このようにしている理由は、DUを使用すると、インターフェースを別の部分にする必要があるからです。このようにすれば、cuda_map (fun x -> x*x)
と書くことができ、タイプ情報が存在するためコンパイルできます。上記の断片は、特に、カーネルのメソッドの引数を表示することになっています。これはHaskellのだった
なら、私はOCamlのGADTsで、それを行うには+ HKTs +タグなしスタイル型クラスを使用することだろうが、F#で私のための唯一の現実的な選択肢は、静的に解決型のparamsを使用してfinally tagless styleを模倣することですが、私はそうではありませんそこにはコンパイラエラーが数えられます。
このスレッドを私が開いた問題に渡すつもりです。
ありがとう、私はあなたの専門知識なしで失われるだろう。編集をご覧ください。あなたのコードは実際にはコンパイルされますが、いくつかの追加メンバーを追加すると、その事が再び破られます。私は理論的にF#が可能であっても、これがミニコンパイラを作る正しい道ではないと思っています。あなたがこれを回避する方法を見つけられるのであれば、私は不思議です。 –
あなたの編集を見た。これがうまくいくのは驚くべきことです。私はこの方法で元のコードを拡張しようとしたが、それもコンパイルされます。 –
はい、もう一度、私は本当に理由を説明することはできません。すでに述べたように、私は[FSharpPlus](https://github.com/gmpl/FSharpPlus)に貢献することはすでに何年も前から行われているため、これらの種類の不整合を作業負荷に分解する専門知識を持っています。興味があれば、図書館に寄稿することもできます。そうすることで、これらすべての一般的な回避策や複雑なものを学ぶことができます。また、達成しようとしていることを他の人と共有することも可能です。 – Gustavo