是否有可能以某种方式使用管道传递带有tupled参数的方法的最后一个参数?
一个例子:
// Member to call
static member Property (expr:Expr<'a -> string>, cfg:EntityInfo<'a>) = cfg.Property expr
// My curry function
let curry f x y = f (x,y)
// My EntityInfo<FileUpload>
let entityInfo = EF.Entity<FileUpload> modelBuilder
我希望能够称之为:
entityInfo |> curry EF.Property <@ fun z -> z.Path @>
而不是
EF.Property(<@ fun z -> z.Path @>, entityInfo)
答案 0 :(得分:2)
我认为这是您问题的简化版本(尽管您要排除太多代码以确定):
type T() = class end
type S =
static member Method(_:int, T) = 'c'
static member Method(_:string, T) = false
let curry f x y = f(x,y)
// won't work
T() |> curry S.Method 1
正如布莱恩所提到的,重载不能很好地与类型推断发挥作用。特别是,由于F#的类型推断从左到右工作,编译器在尝试对1
进行成员查找时不使用int
为S.Method
的事实,这意味着它无法识别正确的过载。在我看来,你有几个选择:
Property
来引用多个不同的操作?每次重载使用StringProperty
,IntProperty
等会更糟吗?通常,重载会使编译器的生活变得更加困难(对于人类维护者来说也是如此)。顺便说一句,我不喜欢命名方法Property
的想法,无论如何...... 在curry
上使用显式类型参数,并指定它们。 E.g。
let curry<'a,'b,'c> f (x:'a) (y:'b) : 'c = f(x,y)
entityInfo |> curry<Expr<_ -> string>,_,_> EF.Property <@ fun z -> z.Path @>
明确指出EF.Property
的类型:
entityInfo |> curry (EF.Property: Expr<_ -> string> * _ -> _) <@ fun z -> z.Path @>
当然,最后两个选项并不是非常简洁,因此它们可能会破坏使用流水线样式的目的。
答案 1 :(得分:0)
这是因为它将实体信息计为EF.Property方法的成员而不是咖喱方法,你应该使用
entityInfo |> curry (EF.Property) (<@ fun z -> z.Path @>)