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