本文介绍了如何解决具有静态解析类型参数的递归映射中的奇怪类型错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 输入CudaInnerExpr< t> = CudaInnerExpr of expr:string with 
member t.Expr = t |>有趣(CudaInnerExpr expr) - > expr

type CudaScalar< t> =名称的CudaScalar:带
的字符串member t.Name = t |>有趣(CudaScalar名称) - >名称

类型CudaAr1D< t> = CudaScalar的CudaAr1D< int> *名称:带
的字符串成员t.Name = t |> fun(CudaAr1D(_,name)) - >名称

类型CudaAr2D< t> = CudaScalar的CudaAr2D< int> * CudaScalar< int> *名称:带
的字符串成员t.Name = t |> fun(CudaAr2D(_,_,name)) - >名称

类型ArgsPrinter = ArgsPrinter with
静态成员inline PrintArg(_:ArgsPrinter,t:CudaScalar< float32>)= sprintffloat%st.Name
静态成员inline PrintArg(_:ArgsPrinter,t:CudaScalar< int>)= sprintfint%st.Name
静态成员inline PrintArg(_:ArgsPrinter,t:CudaAr1D< float32>)= sprintffloat *% st.Name
静态成员inline PrintArg(_:ArgsPrinter,t:CudaAr1D< int>)= sprintfint *%st.Name
静态成员inline PrintArg(_:ArgsPrinter,t :CudaAr2D< float32>)= sprintffloat *%st.Name
静态成员inline PrintArg(_:ArgsPrinter,t:CudaAr2D< int>)= sprintfint *%st.Name

static inline PrintArg(_:ArgsPrinter,(x1,x2))=
let inline print_arg x =
let inline call(tok:^ T)=((^ T or ^ in_):(静态成员PrintArg:ArgsPrinter * ^ in_ - >字符串)tok,x)
调用ArgsPrinter
[| pr int_arg x1; print_arg x2 |] |> String.concat,
static inline PrintArg(_:ArgsPrinter,(x1,x2,x3))=
let inline print_arg x =
let inline call(tok:^ T) =((^ T或^ in_):(静态成员PrintArg:ArgsPrinter * ^ in_ - >字符串)tok,x)
调用ArgsPrinter
[| print_arg x1; print_arg x2; print_arg x3 |] |> String.concat,

在行 static member inline PrintArg(_ :ArgsPrinter,(x1,x2,x3))= ,表达式(x1,x2,x3)给了我下面的错误:

  Script1.fsx(26,52):错误FS0001:此表达式预计有类型
'in_
但是这里有类型
'a *'b *'c

在这里做这个工作吗?

解决方案

在我看来,你想要做这样的事情:

  ... 

静态成员inline PrintArg(_:ArgsPrinter,t:CudaAr2D< float32>)= sprintffloat *%st.Name
静态成员inline PrintArg(_:ArgsPrinter,t:CudaAr2D< int>)= sprintfint *%st.Name

let inline print_arg x =
let inline call(tok:^ T)=((^ T or ^ in_):(静态成员PrintArg:ArgsPrinter * ^ in_ - >字符串)tok,x)
call ArgsPrinter

类型带有
的ArgsPrinter PrintArg(_:ArgsPrinter,(x1,x2))= [| print_arg x1; print_arg x2 |] |> print.arcat,
static member inline PrintArg(_:ArgsPrinter,(x1,x2,x3))= [| print_arg x1; print_arg x2; print_arg x3 |] |>> String.concat,

您在类型中定义泛型函数,因为您将使用它对于最后两个重载,这将成为'递归重载'。



请注意,目前在,实际上是对该技术的简化。

最后注意你的解决方案似乎也是正确的(虽然更详细),但由于某种原因,F#编译器变得困惑,我无法向你解释为什么,但遇到了像这样的许多情况,我所能做的就是找到一个最小的repro,一个解决方法并将其报告给F#球员。约束求解器中仍然有很多问题需要解决。


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.

这篇关于如何解决具有静态解析类型参数的递归映射中的奇怪类型错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 08:23