开发者

Call a function from its name as a string in f#

开发者 https://www.devze.com 2023-03-11 10:40 出处:网络
I 开发者_如何学Cthought that I might be able to do this with quotations - but I can\'t see how.

I 开发者_如何学Cthought that I might be able to do this with quotations - but I can't see how.

Should I just use a table of the functions with their names - or is their a way of doing this?

Thanks.

For more info......

I'm calling a lot of f# functions from excel and I wondered if I could write a f# function

let fs_wrapper (f_name:string) (f_params:list double) = this bit calls fname with f_params

and then use

=fs_wrapper("my_func", 3.14, 2.71)

in the sheet rather than wrap all the functions separately.


You'll need to use standard .NET Reflection to do this. Quotations aren't going to help, because they represent function calls using standard .NET MethodInfo, so you'll need to use reflection anyway. The only benefit of quotations (compared to naive reflection) is that you can compile them, which could give you better performance (but the compilation isn't perfect).

Depending on your specific scenario (e.g. where are the functions located), you'd have to do something like:

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 |])

Unless you need some extensibility or have a large number of functions, using a dictionary containing string as a key and function value as the value may be an easier option:

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

funcs.[name](3.1415)


There are many methods but one way is to use Reflection, for instance:

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

GetMethod optionally takes an array of types that define the signature, but you can skip that if your method is unambiguous.


Following up on what Thomas alluded to, have a look at Using and Abusing the F# Dynamic Lookup Operator by Matthew Podwysocki. It offers a syntactically clean way for doing dynamic lookup in F#.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号