我尝试了两种变体,它们都有同样的问题。
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>'
这让我感到惊讶,因为错误没有出现在Intellisense中,只有当我尝试在F#Interactive中运行它时才会出现。我不确定再次在这做什么。我可能会过多地滥用类型系统,但我决心以无标记的方式完成这个Cuda编译器,无论如何。我需要这样才能传播后期阶段的类型信息。
编辑:Gustavo的修复工作正常,但是当我再往前走时它会再次破坏。
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 ", "
再次,在最后两行中,我表现出与pt完全相同的错误。其中一个。我在这里要做的是成为嵌入式Cuda DSL的一部分。之所以我这样做而不是使用DU,是因为使用DUs,我必须将接口作为一个单独的部分。如果我这样做,我将能够编写cuda_map (fun x -> x*x)
并编译它,因为类型信息将存在。特别是上面的片段应该打印出内核方法的参数。
如果这是Haskell,我会在Ocaml GADT中使用类型类+ HKTs +无标记样式来实现它,但在F#中,对我来说唯一真实的选择是使用静态解析类型参数来模仿finally tagless style,但是我没有指望存在编译器错误。
我打算将这个帖子传递给我打开的问题。
答案 0 :(得分:4)
我不确定我是否理解你的问题/你想要实现的目标。
我不知道为什么你在这个类型的中间插入了这个函数,在你之前的问题中它是必要的但是在这里我不这么认为。
如果你按自然顺序编写它,它会编译:
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 with
static member inline PrintArg(_: ArgsPrinter, t: CudaScalar< ^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 ", "
type ArgsPrinter with
static member inline PrintArg(_: ArgsPrinter, (x1, x2, x3)) =
[|print_arg x1;print_arg x2;print_arg x3|] |> String.concat ", "
我的意思是'延伸'两次。