2015-10-13 73 views
0

給出:如何爲此Func調用編寫繼續傳遞樣式?

open System 
open System.Linq.Expressions 
open Microsoft.FSharp.Quotations 
open Microsoft.FSharp.Linq.RuntimeHelpers 
open FizzWare.NBuilder 

let toLinq (expr: Expr<'a -> 'b>) = 
    let linq = LeafExpressionConverter.QuotationToExpression expr 
    let call = linq :?> MethodCallExpression 
    let lambda = call.Arguments.[0] :?> LambdaExpression 
    Expression.Lambda<Func<'a,'b>>(lambda.Body, lambda.Parameters) 

let inline with'<'a,'b> (f:Expr<'a->'b>) (value:'b) (operable:IOperable<'a>) = 
    let f = toLinq f 
    operable.With(f,value) 

let size = 20 
    let builderList = 
     Builder<dbEncounter.ServiceTypes.Patients>.CreateListOfSize(size).All() 
     |> with' <@ fun x -> x.PatientID @> 0 
     |> with' <@ fun x -> x.ForeignEHRID @> (Nullable 0) 
     |> with' <@ fun x -> x.PatientInfoID @> (Nullable 0) 
     |> (fun b -> b.With(fun x-> x.PatientGUID <- Nullable (Guid.NewGuid()); x.PatientGUID)) 
     |> withf (fun x-> x.PatientGUID <- Nullable (Guid.NewGuid()); x.PatientGUID) // this line doesn't compile as a replacement for the previous line 

我試圖在寫withf

let inline withf<'a,'b> (f:Func<'a,_>) (operable:IOperable<'a>) = 
operable.With(f) 

上的withf試圖使用,以取代其他選項的錯誤是

Error This function takes too many arguments, or is used in a context where a function is not expected

+2

'Func'是一個.NET委託類型,而不是F#函數類型,所以你可能想用'(f:'a - >'b)'作爲你的參數,然後在''withf'實現中創建一個委託。 – kvb

回答

1

答案感謝找到以@kvb的另一個問題的另一個答案

Interop between F# and C# lambdas

我只需要調用Func構造像這樣:

let inline withf<'a,'b> (f:'a->'b) (operable:IOperable<'a>) = 
    operable.With(Func<'a,'b>(f)) 

所以現在這個工程:

let makePatients size = 
    let builderList = 
     Builder<dbEncounter.ServiceTypes.Patients>.CreateListOfSize(size).All() 
     |> with' <@ fun x -> x.PatientID @> 0 
     |> with' <@ fun x -> x.ForeignEHRID @> (Nullable 0) 
     |> with' <@ fun x -> x.PatientInfoID @> (Nullable 0) 
     //|> (fun b -> b.With(fun x-> x.PatientGUID <- Nullable (Guid.NewGuid()); x.PatientGUID)) 
     |> withf (fun x-> x.PatientGUID <- Nullable (Guid.NewGuid()); x.PatientGUID)