代码之家  ›  专栏  ›  技术社区  ›  Gerard

f 35;:srtp静态扩展方法类型匹配不一致

  •  4
  • Gerard  · 技术社区  · 8 年前

    我想用 PrintfFormat 要键入强制解析程序的解析,它最初似乎适用于 int 但同样的方法 string 不起作用…当float起作用时,我认为是value/ref类型的问题,但随后尝试了 bool 这可不像弦的作用。

    内景 &安培 float 工作, 一串 &安培 布尔 不要!是吗?

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

        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 函数格式字符串输入为 The type 'string' does not support the operator 'ParseApply' ,同样地, result4 错误是 The type 'bool' does not support the operator 'ParseApply' 是的。

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

    2 回复  |  直到 8 年前
        1
  •  5
  •   Gus    8 年前

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

    另见 Error on Extension Methods when Inlining

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

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

    这可以用命名方法来编写,方法是复制操作符trait调用被取消的方式。

        2
  •  5
  •   Chester Husk    8 年前

    我认为这在f编译器中仍然是一个空白,即扩展成员对类型约束不可见。有WIP公关 here 这就弥补了差距。