F# 如何统一这个成员方法和内联函数的签名

F# 如何统一这个成员方法和内联函数的签名,f#,F#,鉴于此代码 type Baz = Baz of int with static member bar f (Baz(b)) = f b let inline foo< ^T, ^U when ^T : (static member bar : (^U -> ^T) -> ^T -> ^T)> (f:(^U -> ^T)) (t:^T) : ^T = (^T : (static member bar : (^U -> ^T) -

鉴于此代码

type Baz = Baz of int with
    static member bar f (Baz(b)) = f b

let inline foo< ^T, ^U when ^T : (static member bar : (^U -> ^T) -> ^T -> ^T)>
    (f:(^U -> ^T)) (t:^T) : ^T = 
    (^T : (static member bar : (^U -> ^T) -> ^T -> ^T) f, t )

let x = foo (fun x -> (Baz 0)) (Baz 1)
我假设我的静态成员的签名不能真正统一到
(^U->^T)->^T->^T

如何解决此问题?

查看(即切换回成员函数)和您的评论,也许这会起作用:

type Baz = Baz of int with
    member this.bar (f: 'a -> 'b): 'b = match this with
                                        | Baz i ->  f i

let inline foo (f: ^U -> ^T) (t:^T)  = 
    let foo' = (^T : (member bar : (^U -> ^T) -> ^T) (t, f))
    foo'

let x = foo (fun x -> (Baz 0)) (Baz 1)

// This returns Baz 0
printfn "%A" x

Baz.bar
的类型是
(int->'a)->Baz->'a
,它不适合
(^U->^t)->^t->^t)
@MarkSeemann是的,我知道-但是如果
(^U->^t>)^t->^t
(int->'a)->Baz->^a
的超集,从左边开始,如果
int
取代
^U
,而
'a
取代
^T
,那么签名应该是
(int->'a)->'a->'a
,而不是。。。除非我遗漏了什么…@MarkSeemann yea,所以我也这样想,并将成员函数更改为
静态成员栏(f:'a->'b)(b:'b):'b=将b与| Baz(I)->fi匹配,从而生成以下签名
静态成员栏:f:(int->Baz)->b:Baz->Baz
。因此,这最终应该与
(^U->^T)->^T->^T
相同,只是它不是:-(所有这些的原因都在这里;-)
type Baz = Baz of int with
    member this.bar (f: 'a -> 'b): 'b = match this with
                                        | Baz i ->  f i

let inline foo (f: ^U -> ^T) (t:^T)  = 
    let foo' = (^T : (member bar : (^U -> ^T) -> ^T) (t, f))
    foo'

let x = foo (fun x -> (Baz 0)) (Baz 1)

// This returns Baz 0
printfn "%A" x