F #: Несоответствующее сопоставление типа метода статического расширения SRTP - PullRequest
0 голосов
/ 24 июня 2018

Я пытаюсь использовать 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 строки формата функции: The type 'string' does not support the operator 'ParseApply', аналогично result4 ошибка The type 'bool' does not support the operator 'ParseApply'.

Я не знаю, почему это несоответствие, это ошибка или я что-то упустил?

Ответы [ 2 ]

0 голосов
/ 24 июня 2018

Как сказал @ChesterHusk, в настоящий момент расширения не видны для вызовов черты.

См. Также Ошибка методов расширения при встраивании

На данный моментспособ заставить это работать, используя промежуточный класс с операторным вызовом черты (операторы обычно смотрят в свой собственный класс и в определяемые пользователем классы).

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

Это может быть написано с именованными методами путем репликацииспособ, которым операторы черт-вызова обескуражены.

0 голосов
/ 24 июня 2018

Я думаю, что это все еще открытый пробел в компиляторе F #, то есть, что члены расширения не видны для ограничений типов.Здесь есть WIP PR , который перекрывает пропасть.

...