gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 22:39:47 27 4
gpt4 key购买 nike

我正在尝试使用 PrintfFormat 键入强制解析器的解析,它最初似乎适用于 int 但后来使用相同的方法 string没用...虽然 float 确实有效,所以我认为是 Value/Ref 类型问题,但后来尝试了 bool ,但它不像 String 那样工作。

int & float 工作,string & bool 不行!?

(ParseApply 方法现在是虚拟实现)

    type System.String  with static member inline ParseApply (path:string) (fn: string -> ^b) : ^b = fn ""
type System.Int32 with static member inline ParseApply (path:string) (fn: int -> ^b) : ^b = fn 0
type System.Double with static member inline ParseApply (path:string) (fn: float -> ^b) : ^b = fn 0.
type System.Boolean with static member inline ParseApply (path:string) (fn: bool -> ^b) : ^b = fn true

let inline parser (fmt:PrintfFormat< ^a -> ^b,_,_,^b>) (fn:^a -> ^b) (v:string) : ^b
when ^a : (static member ParseApply: string -> (^a -> ^b) -> ^b) =
(^a : (static member ParseApply: string -> (^a -> ^b) -> ^b)(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 = patternTest "adfadf%i" (fun v -> printfn "%i" v; Unchecked.defaultof<Action<unit>> ) // works
let parseFn2 = patternTest "adf%s245" (fun v -> printfn "%s" v; Unchecked.defaultof<Action<unit>> ) // ERROR
let parseFn3 = patternTest "adfadf%f" (fun v -> printfn "%f" v; Unchecked.defaultof<Action<unit>> ) // works
let parseFn4 = patternTest "adfadf%b" (fun v -> printfn "%b" v; Unchecked.defaultof<Action<unit>> ) // ERROR

我在result2函数格式字符串输入上得到的错误是类型'string'不支持运算符'ParseApply',同样,result4错误是类型'bool'不支持运算符'ParseApply'

我不知道为什么会出现这种不一致,是错误还是我遗漏了什么?

最佳答案

正如@ChesterHusk 所说,目前扩展对特征调用不可见。

另见 Error on Extension Methods when Inlining

目前,使其工作的方法是使用带有类似运算符的特征调用的中间类(运算符通常查看他们自己的类和用户定义的类)。

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

这可以通过复制操作符特征调用脱糖的方式来使用命名方法编写。

关于F#:SRTP静态扩展方法类型匹配不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51009883/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com