0

given:

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

my attempt at writing withf:

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

the error on attempted usage of withf to replace the other option is

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

Maslow
  • 18,464
  • 20
  • 106
  • 193
  • 2
    `Func` is a .NET delegate type, not an F# function type, so you might want to use `(f:'a -> 'b)` as your argument instead and then create a delegate from it within your `withf` implementation. – kvb Oct 13 '15 at 14:05

1 Answers1

1

Found the answer thanks to @kvb 's other answer to another question

Interop between F# and C# lambdas

I just need to call the Func constructor like so:

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

so now this works:

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)
Community
  • 1
  • 1
Maslow
  • 18,464
  • 20
  • 106
  • 193