F#动态运算符可同时访问函数和函数名称 [英] F# dynamic operator giving access both to function and function name

查看:66
本文介绍了F#动态运算符可同时访问函数和函数名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出多个函数 test1 test2 ,...属于一个模块:

Given a number of functions test1, test2, ... belonging to a module:

module Checks =
    let test1 x = ...
    let test2 x = ...
    ...

如何使用(?)运算符同时访问函数名称和功能本身?结果应如下所示:

how can the (?) operator be used to give access to both the function name and the function itself? The result should look like:

let name, func = Checks?test1
assert(name = "test1")
assert(func(x) = Checks.test1(x)) //whatever x is (test1 is known to be pure)


推荐答案

下面是一些示例代码,展示了其中的一些内容。我将 D 用作 Checks 模块加函数名的动态访问。

Here's some sample code that shows off some of this. I use D as the 'dynamic' access of the Checks module plus function name.

module Checks = 
    let test1(x) = printfn "test1 %d" x
    let test2(x,y) = printfn "test2 %s %d" x y

type MyDynamic() = class end
let D = new MyDynamic()
let (?) (md:MyDynamic) fname : (string * ('a -> 'r)) =
    let a = md.GetType().Assembly
    let t = a.GetType("Program+Checks")
    let m = t.GetMethod(fname)
    let f arg = 
        let at = arg.GetType()
        let fsharpArgs = 
            if at.IsGenericType && at.GetGenericTypeDefinition().FullName.StartsWith("System.Tuple`") then
                Microsoft.FSharp.Reflection.FSharpValue.GetTupleFields(arg)
            else
                [| box arg |]
        unbox(m.Invoke(null, fsharpArgs))
    fname, f

let Main() =
    let x = 42
    let s = "foo"
    let name, func = D?test1 
    assert(name = "test1") 
    assert(func(x) = Checks.test1(x))

    let name, func = D?test2
    assert(name = "test2") 
    assert(func(s,x) = Checks.test2(s,x))

    System.Console.ReadKey()

Main()

这篇关于F#动态运算符可同时访问函数和函数名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆