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>)