lambda - F# 表达式仅在泛型内自动从函数转换?
问题描述
我试图将一个函数传递给一个接受表达式的函数,但它只适用于泛型函数。
这是我想要的,但它不起作用:
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# 规范,隐式转换为 LINQ 表达式是 F# 的方法应用程序解析(第 14.4 节)的一部分,这是一个比简单函数应用程序解析(第 14.3 节)更复杂的过程。转换为 LINQ 表达式在第 8.13.7.4 节中有具体描述,其中说:
...类型导向的转换使 F# 表达式能够在方法调用时隐式转换为 LINQ 表达式。转换由 System.Linq.Expressions.Expression 类型的参数驱动。
(强调补充。)
推荐阅读
- vagrant - VBoxManage.exe:错误:VMDK:无法创建新文件:box-disk001.vmdk' (VERR_ALREADY_EXISTS)
- python - Python:如何在声明列表的同一行中附加到列表?
- php - CakePHP:表格重新排序
- typescript - 构建组合接口阵列
- typescript - 将文档复制到另一个集合 mongoose 时出现问题
- sip - 相同编解码器但不同 fmtp 行的重复有效负载类型是否有效?
- java - java - 如何从java中的子级为最终静态变量赋值?
- ruby-on-rails - 在 Rails 中打开显示路径时保存数据
- cherrypy - 如何在 CherryPy 中实现多个 POST 方法
- python - 如何使用 Networkx 包显示具有更好分离度的网络?