Is there a way to do somehow overload a function?
Let's take those 3 functions:
// Returns StringPropertyInfo
let stringProperty (expr:Expr<'a -> string>) (cfg:EntityInfo<'a>) =
cfg.Property expr
// Returns DatePropertyInfo
let dateProperty (expr:Expr<'a -> System.DateTime>) (cfg:EntityInfo<'a>) =
cfg.Property expr
// Returns BytePropertyInfo
let byteProperty (expr:Expr<'a -> System.Byte>) (cfg:EntityInfo<'a>) =
cfg.Property expr
is there a way to merge them all into just:
let property expr cfg = ....
if not, whats the most neat way to accomplish something similar?
If you want to use an approach based on discriminated unions, then I think the declaration is more suitable (as you don't need to manipulate with quotations). Slight modification of the type suggested by Alex is:
type PropertyInfo<'a> =
| String of Expr<'a -> string>
| Date of Expr<'a -> System.DateTime>
| ...
Then you'd write something like:
let property (pi:PropertyInfo<'a>) (cfg:EntityInfo<'a>) =
match pi with
| String e -> cfg.Property e
| ...
cfg |> property (String <@ fun e -> e.Foo @>)
Another option would be to implement property
as a static member of a type, in which case you can use usual overloading (similar to C#). Something like:
type EF =
static member property (expr:Expr<'a -> string>) (cfg:EntityInfo<'a>) =
cfg.Property expr
static member property (expr:Expr<'a -> System.DateTime>) (cfg:EntityInfo<'a>) =
cfg.Property expr
static member property (expr:Expr<'a -> System.Byte>) (cfg:EntityInfo<'a>) =
cfg.Property expr
Then you'd write:
cfg |> EF.property <@ e -> e.Foo @>
Finally, you could also make it a bit simpler (but less safer) by making the function fully generic and doing dynamic type test (to decide what return type is used). Something like:
let property<'a, 'r> (e:Expr<'a -> 'r>) (cfg:EntityInfo<'a>) =
if typeof<'r> = typeof<string> then
// ...
Short answer, no. There's another question dealing with this here.
You can however overload methods in classes etc. otherwise the .NET integration wouldn't work too well. This is one possible solution albeit not in my eyes, a pretty one.
You could put them in different sub-modules.
Perhaps you could make a generic function and decide the return type through one of the parameters. I'm too much of a newbie when it comes to the type inference to say for certain though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With