F# 表达式仅在泛型中自动从函数转换?
F# Expression is automatically converted from function only within generics?
我正在尝试将一个函数传递给一个接受表达式的函数,但它只适用于泛型函数。
这个是我想要的,但它不起作用:
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)
为什么示例 1. 不起作用?
差异不是由泛型引起的。发生这种情况是因为一个示例是函数调用,另一个示例是方法调用。因此,即使您将函数设为泛型,它仍然无法正常工作:
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
根据 F# spec,到 LINQ 表达式的隐式转换是 F# 方法应用程序解析(第 14.4 节)的一部分,这是一个比简单函数应用程序解析(第 14.3 节)更复杂的过程。转换为 LINQ 表达式在 8.13.7.4 节中有具体描述,其中说:
... 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.
(强调已添加。)
我正在尝试将一个函数传递给一个接受表达式的函数,但它只适用于泛型函数。
这个是我想要的,但它不起作用:
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)
为什么示例 1. 不起作用?
差异不是由泛型引起的。发生这种情况是因为一个示例是函数调用,另一个示例是方法调用。因此,即使您将函数设为泛型,它仍然无法正常工作:
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
根据 F# spec,到 LINQ 表达式的隐式转换是 F# 方法应用程序解析(第 14.4 节)的一部分,这是一个比简单函数应用程序解析(第 14.3 节)更复杂的过程。转换为 LINQ 表达式在 8.13.7.4 节中有具体描述,其中说:
... 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.
(强调已添加。)