F# 以编程方式用修饰符包装所有模块的函数

F# 以编程方式用修饰符包装所有模块的函数,f#,wrapper,decorator,trace,F#,Wrapper,Decorator,Trace,需要追踪。装饰程序应该打印函数名、参数值和返回值。与其每次都为每个函数编写一个decorator,不如通过编程实现这一点。可以通过反射来发现当前函数名。可以使用用于日志记录的内联函数轻松修饰函数: let inline log args f = let mi = System.Reflection.MethodBase.GetCurrentMethod() let result = f () printf "%s %A -> %A" mi.Name args result

需要追踪。装饰程序应该打印函数名、参数值和返回值。与其每次都为每个函数编写一个decorator,不如通过编程实现这一点。

可以通过反射来发现当前函数名。可以使用用于日志记录的内联函数轻松修饰函数:

let inline log args f  =
  let mi = System.Reflection.MethodBase.GetCurrentMethod()
  let result = f ()
  printf "%s %A -> %A" mi.Name args result

let add a b = log (a,b) (fun () -> a + b)

add 1 1
哪个打印:添加1,1->2

编辑:另一个选项是创建换行功能,即:

let inline wrap f = 
  fun ps ->
    let result = f args
    printfn "%A -> %A" args result
    result

let add (a,b) = a + b

wrap add (1,1)
但是,在本例中,没有一种简单的方法可以通过编程方式检索函数名


另一种选择可能是开发一个类型提供程序,它将程序集路径作为参数,并提供所有成员的包装版本。

当前函数名可以通过反射来查找。可以使用用于日志记录的内联函数轻松修饰函数:

let inline log args f  =
  let mi = System.Reflection.MethodBase.GetCurrentMethod()
  let result = f ()
  printf "%s %A -> %A" mi.Name args result

let add a b = log (a,b) (fun () -> a + b)

add 1 1
哪个打印:添加1,1->2

编辑:另一个选项是创建换行功能,即:

let inline wrap f = 
  fun ps ->
    let result = f args
    printfn "%A -> %A" args result
    result

let add (a,b) = a + b

wrap add (1,1)
但是,在本例中,没有一种简单的方法可以通过编程方式检索函数名


另一种选择可能是开发一个类型提供程序,它将程序集路径作为参数,并提供所有成员的包装版本。

我以前也有同样的愿望,发现目前没有针对F的自动解决方案

见:

虽然OCaml的带有时间旅行的跟踪功能是最有用的调试功能,可以与期望的功能进行比较,但它并不完全适合;但是当我使用OCaml时,它是我使用的第一个检查工具

见:

此外,使用PostSharp的建议是另一个很好的建议,正如PostSharp首席工程师的回应所指出的:

PostSharp不正式支持F

除了按照建议使用反射(我没有尝试过),我找到的最佳解决方案是手动修改要跟踪的每个函数(如中所述),并使用将结果保存到单独的日志文件中

见:

另一个途径是检查的工作,因为有很多工作正在做,以添加额外的工具与F一起使用

基本上,我发现随着我的F技能的提高,我的需求也在增加 使用调试器或跟踪工具

目前,当我遇到需要此级别检查的问题时,添加中所述的检查代码有助于解决我的误解


同样值得注意的是,从C世界到F世界的人倾向于期望调试器同样有用。记住,命令式语言倾向于处理变量中的数据,调试器用于检查这些变量中的值,而函数式编程中,至少对我来说,我尝试避免可变值,因此需要检查的唯一值是传递给函数的值,而不是其他值,这样就减少或避免了对调试器或检查的需求,而不仅仅是问题功能。

我以前也有同样的愿望,发现目前没有针对F的自动解决方案

见:

虽然OCaml的带有时间旅行的跟踪功能是最有用的调试功能,可以与期望的功能进行比较,但它并不完全适合;但是当我使用OCaml时,它是我使用的第一个检查工具

见:

此外,使用PostSharp的建议是另一个很好的建议,正如PostSharp首席工程师的回应所指出的:

PostSharp不正式支持F

除了按照建议使用反射(我没有尝试过),我找到的最佳解决方案是手动修改要跟踪的每个函数(如中所述),并使用将结果保存到单独的日志文件中

见:

另一个途径是检查的工作,因为有很多工作正在做,以添加额外的工具与F一起使用

基本上,我发现随着我的F技能的提高,我的需求也在增加 使用调试器或跟踪工具

目前,当我遇到需要此级别检查的问题时,添加中所述的检查代码有助于解决我的误解


同样值得注意的是,从C世界到F世界的人倾向于期望调试器同样有用。记住,命令式语言倾向于处理变量中的数据,调试器用于检查这些变量中的值,而函数式编程中,至少对我来说,我尝试避免可变值,因此需要检查的唯一值是传递给函数的值,而不是其他值,这样就减少或避免了除问题功能之外的调试器或检查的需要。

看看AOP解决方案,例如PostSharp。看看AOP解决方案,例如PostSharp。太好了。但我必须重写首字母f。有吗
e简单替换f->wrapperFunction f的可能性?请注意,为了安全起见,您可能需要在包含对log的调用的方法上添加[],否则可能会将其内联到自己的调用方中,从而产生误导性的跟踪。@OlegLeonov为使其看起来不那么具有视觉干扰性,请添加一些一元运算符,例如let!=wrapGreat。但我必须重写首字母f。是否有可能进行简单替换f->wrapperFunction f?请注意,为了安全起见,您可能需要在包含对log的调用的方法上添加[],否则它可能被内联到自己的调用方中,从而产生误导性的跟踪。@OlegLeonov为使其看起来不那么具有视觉干扰性,请添加一些一元运算符,例如let!=非常感谢你的详细回答。非常感谢你的详细回答。