Alex 75
Alex 75

Reputation: 3266

F# Expression is automatically converted from function only within generics?

I'm trying to pass a function to a function that accepts an Expression but it only works in the function is a generics one.

This one is what I want but it does not work:

open System
open System.Linq.Expressions
open MongoDB.Driver

type MyObject = { Name:string}

type MyClass () =

    // I want to use this
    let createFilter (field:Expression<Func<MyObject, string>>, value:string):FilterDefinition<MyObject> =
        FilterDefinitionBuilder<MyObject>().Eq(field, value)

    member this.CreateFilter<'T> (field:Expression<Func<'T, string>>, value:string):FilterDefinition<'T> =
        FilterDefinitionBuilder<'T>().Eq(field, value)

    member this.DoSomething(name:string) =

        // 1. this does NOT work
        let filter = createFilter( (fun x -> x.Name) , name)

        // 2. this one works fine
        let filter = this.CreateFilter( (fun x -> x.Name) , name)

Why the example 1. does not work?

Upvotes: 2

Views: 95

Answers (1)

Brian Berns
Brian Berns

Reputation: 17153

The difference isn't due to generics. It happens because one example is a function call and the other is a method call. So even if you make the function generic, it still won't work:

let createFilter (field:Expression<Func<'T, string>>, value:string):FilterDefinition<'T> =
    FilterDefinitionBuilder<'T>().Eq(field, value)

let filter = createFilter( (fun x -> x.Name) , name)   // ERROR

Per the F# spec, implicit conversion to LINQ expressions is part of F#'s method application resolution (section 14.4), which is a more complex process than simple function application resolution (section 14.3). Conversion to LINQ expressions is specifically described in section 8.13.7.4, which says:

... type-directed conversion enables an F# expression to be implicitly converted to a LINQ expression at a method call. Conversion is driven by an argument of type System.Linq.Expressions.Expression.

(Emphasis added.)

Upvotes: 2

Related Questions