在f#中将函数的名称作为字符串调用

时间:2011-06-03 21:27:35

标签: f# quotations

我以为我可以用引号做到这一点 - 但我看不出怎么做。

我应该只使用一个功能表和他们的名字 - 或者他们是这样做的吗?

感谢。

了解更多信息......

我从excel调用了很多f#函数,我想知道我是否可以写一个f#函数

让fs_wrapper(f_name:string)(f_params:list double)=     这个位用f_params

调用fname

然后使用

= fs_wrapper(“my_func”,3.14,2.71)

在工作表中

而不是分别包装所有功能。

3 个答案:

答案 0 :(得分:10)

您需要使用标准的.NET Reflection来执行此操作。引号不会有帮助,因为它们使用标准.NET MethodInfo表示函数调用,因此您无论如何都需要使用反射。引用的唯一好处(与天真的反射相比)是你可以编译它们,这可以提供更好的性能(但编译并不完美)。

根据您的具体情况(例如,功能位于何处),您必须执行以下操作:

module Functions =
  let sin x = sin(x)
  let sqrt y = sqrt(y)

open System.Reflection

let moduleInfo = 
  Assembly.GetExecutingAssembly().GetTypes()
  |> Seq.find (fun t -> t.Name = "Functions")

let name = "sin"
moduleInfo.GetMethod(name).Invoke(null, [| box 3.1415 |])

除非您需要一些可扩展性或具有大量函数,否则使用包含字符串作为键的字典和函数值作为值可能是一个更容易的选项:

let funcs = 
  dict [ "sin", Functions.sin;
         "sqrt", Functions.sqrt ]

funcs.[name](3.1415)

答案 1 :(得分:2)

有很多方法,但有一种方法是使用Reflection,例如:

typeof<int>.GetMethod("ToString", System.Type.EmptyTypes).Invoke(1, null)
typeof<int>.GetMethod("Parse", [|typeof<string>|]).Invoke(null, [|"112"|])

GetMethod可选地采用一组定义签名的类型,但是如果你的方法是明确的,你可以跳过它。

答案 2 :(得分:1)

跟进托马斯所提到的,请看马修波德维索基的Using and Abusing the F# Dynamic Lookup Operator。它提供了一种语法清晰的方式,可以在F#中进行动态查找。