F# - Pipeline with tupled parameters
Is it possible to somehow use a pipeline to pass开发者_如何学编程 in the last argument of a method with tupled parameters?
An example:
// 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
I want to be able to call it like:
entityInfo |> curry EF.Property <@ fun z -> z.Path @>
instead of
EF.Property(<@ fun z -> z.Path @>, entityInfo)
I believe that this is a simplified version of your problem (although you're excluding too much code to be sure):
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
As Brian mentions, overloading doesn't play nicely with type inference. In particular, since F#'s type inference works left-to-right, the compiler does not use the fact that 1
is an int
when trying to do the member lookup for S.Method
, which means that it can't identify the correct overload. As I see it, you have a few options:
- Use distinct method names. Is there a reason that you have to use
Property
to refer to multiple different operations? Would it be much worse to useStringProperty
,IntProperty
, etc. for each overload? In general, overloading makes life harder for the compiler (and often for human maintainers, too). As an aside, I don't like the idea of naming a methodProperty
, anyway... Use explicit type parameters on
curry
, and specify them. 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 @>
Explicitly indicate the type of
EF.Property
:entityInfo |> curry (EF.Property: Expr<_ -> string> * _ -> _) <@ fun z -> z.Path @>
Of course, these last two options aren't very concise, so they may defeat the purpose of using the pipelined style.
It is because it is counting entity info as an member of EF.Propery method instead of curry method, you should use
entityInfo |> curry (EF.Property) (<@ fun z -> z.Path @>)
精彩评论