F#:SRTP静态扩展方法类型匹配不一致

F#:SRTP静态扩展方法类型匹配不一致,f#,constraints,extension-methods,F#,Constraints,Extension Methods,我试图使用printformat来强制解析器的解析,它最初似乎对int有效,但对string的相同方法不起作用。。。虽然float确实有效,所以我认为这是Value/Ref类型的问题,但后来尝试了bool,但效果与String不同 int&float工作,string&bool不工作 (ParseApply方法目前是虚拟实现) 键入System.String并使用静态成员内联语法分析应用(路径:String)(fn:String->^b):^b=fn“” 键入System.Int32并使用静态成

我试图使用
printformat
来强制解析器的解析,它最初似乎对
int
有效,但对
string
的相同方法不起作用。。。虽然float确实有效,所以我认为这是Value/Ref类型的问题,但后来尝试了
bool
,但效果与String不同

int
&
float
工作,
string
&
bool
不工作

(ParseApply方法目前是虚拟实现)

键入System.String并使用静态成员内联语法分析应用(路径:String)(fn:String->^b):^b=fn“”
键入System.Int32并使用静态成员内联语法分析应用(路径:字符串)(fn:int->^b):^b=fn 0
键入System.Double并使用静态成员内联ParseApply(路径:字符串)(fn:float->^b):^b=fn 0。
键入System.Boolean和静态成员内联ParseApply(路径:字符串)(fn:bool->^b):^b=fn true
let内联解析器(fmt:printformat<^a->^b,{,},{,^b>)(fn:^a->^b)(v:string):^b
^a时:(静态成员解析应用:字符串->(^a->^b)->^b)=
(^a:(静态成员解析应用:字符串->(^a->^b)->^b)(v,fn))
让内联模式测试(fmt:printformat<^a->Action<^T>,u,u,Action<^T>)(fn:^a->Action<^T>)v:Action<^T>=解析器fmt fn v
让parseFn1=pattertest“adfadf%i”(fun v->printfn“%i”v;Unchecked.defaultof)//工作
让parseFn2=pattertest“adf%s245”(fun v->printfn“%s”v;Unchecked.defaultof)//错误
让parseFn3=pattertest“adfadf%f”(fun v->printfn“%f”v;Unchecked.defaultof)//工作
让parseFn4=pattertest“adfadf%b”(fun v->printfn“%b”v;Unchecked.defaultof)//错误
我在
result2
函数格式字符串输入中遇到的错误是
类型“string”不支持运算符“ParseApply”
,类似地,
result4
错误是
类型“bool”不支持运算符“ParseApply”


我不知道为什么会有这种不一致,是一个bug还是我遗漏了什么?

我认为这仍然是F#编译器中的一个空白,即扩展成员对类型约束不可见。WIP PR弥补了这一差距。

正如@ChesterHusk所说,目前trait调用看不到扩展

另见

目前,让它工作的方法是使用一个中间类和一个类似操作符的trait调用(操作符通常查看自己的类和用户定义的类)

开放系统
类型T=T,带
静态成员内联($)(T,\:字符串):\u->\ u->^ b=fun(路径:字符串)(fn:string->^b)->fn“”
静态成员内联($)(T,[uu:int):[u->\ u->^ b=fun(路径:字符串)(fn:int->^b)->fn 0
静态成员内联($)(T,\:float):\u->\ u->^ b=fun(路径:string)(fn:float->^b)->fn 0。
静态成员内联($)(T,\:bool):\>\^b=fun(路径:string)(fn:bool->^b)->fn true
让内联解析器(fmt:printformat<^a->^b,{,{,},^b>)(fn:^a->^b)(v:string):^b=(T$Unchecked.defaultof<^a>)v fn
让内联模式测试(fmt:printformat<^a->Action<^T>,u,u,Action<^T>)(fn:^a->Action<^T>)v:Action<^T>=解析器fmt fn v
让parseFn1=parser“adfadf%i”(fun v->printfn“%i”v;未选中。defaultof)
让parseFn2=parser“adf%s245”(fun v->printfn“%s”v;未选中。defaultof)
让parseFn3=parser“adfadf%f”(fun v->printfn“%f”v;未选中。defaultof)
让parseFn4=parser“adfadf%b”(fun v->printfn“%b”v;未选中。defaultof)

这可以通过复制操作符trait调用的设计方式,使用命名方法编写。

感谢@ChesterHusk,很高兴知道在哪里监视Hanks@Gustavo提供了解决方案,您的解决方案运行良好。
open System

type T = T with
    static member inline ($) (T, _:string) : _ ->_ -> ^b = fun (path:string) (fn: string -> ^b)-> fn ""
    static member inline ($) (T, _:int)    : _ ->_ -> ^b = fun (path:string) (fn: int   -> ^b) -> fn 0
    static member inline ($) (T, _:float)  : _ ->_ -> ^b = fun (path:string) (fn: float -> ^b) -> fn 0.
    static member inline ($) (T, _:bool)   : _ ->_ -> ^b = fun (path:string) (fn: bool -> ^b)  -> fn true

let inline parser (fmt:PrintfFormat< ^a -> ^b,_,_,^b>) (fn:^a -> ^b) (v:string) : ^b = (T $  Unchecked.defaultof< ^a> ) v fn

let inline patternTest (fmt:PrintfFormat< ^a -> Action< ^T>,_,_,Action< ^T>>) (fn:^a -> Action< ^T>) v : Action< ^T> = parser fmt fn v

let parseFn1 = parser "adfadf%i" (fun v -> printfn "%i" v; Unchecked.defaultof<int>)
let parseFn2 = parser "adf%s245" (fun v -> printfn "%s" v; Unchecked.defaultof<string>)
let parseFn3 = parser "adfadf%f" (fun v -> printfn "%f" v; Unchecked.defaultof<float>)
let parseFn4 = parser "adfadf%b" (fun v -> printfn "%b" v; Unchecked.defaultof<bool>)