Generics OCaml中的通用定时器高阶函数
我试图在OCaml中实现一个通用计时器函数,该函数将以任意算术和返回类型'r的函数作为输入,并返回具有以下内容的函数:Generics OCaml中的通用定时器高阶函数,generics,ocaml,Generics,Ocaml,我试图在OCaml中实现一个通用计时器函数,该函数将以任意算术和返回类型'r的函数作为输入,并返回具有以下内容的函数: 输入参数的相同算术性和类型 ,及 返回类型float*'r,其中float将是函数中所用时间的度量(例如,Sys.time()报告) 问题是我不能以这样一种方式实现它,即它可以处理任何类型的函数。例如,以下代码: let timer f = let timerf x y =
- 输入参数的相同算术性和类型 ,及
- 返回类型
,其中float将是函数中所用时间的度量(例如,float*'r
报告)Sys.time()
仅适用于输入算术2的函数。对于我来说,如何将它推广到处理任何算术函数是不明显的。我希望部分函数应用程序能以某种方式神奇地解决这个难题,但我无法让它正常工作。我理解你的意图,即制作任意算术的计时器函数。但在OCaml中,您不能以简单的方式完成这项工作 此外,只有一个参数的计时器功能在实践中已足够使用:
let timer f x =
let t0 = Sys.time()
in let result = f x
in let diff = Sys.time() -. t0
in diff, result
由于具有任意算术性的任何函数g
都可以通过以下方式轻松传递到计时器
:
let diff, result = timer (fun () -> g x1 x2 x3 ... xN) ()
或更好地使用部分应用程序(如@Andreas所建议):
关于pad解决方案的评论过于冗长,不适合发表评论 实际上,我发现通过传递
()
而不是延迟参数来强制执行f:unit->'a
是一种更好的设计
let timer f =
let t0 = Sys.time() in
let result = f () in
let t1 = Sys.time() in
t1 -. t0, result
原因是我经常使用以下模式:
let fun_to_test = match some_configuration with ... in
timer fun_to_test
pad的设计一开始更具吸引力,因为它更具一般性,鼓励您改为:
let fun_to_test, arg = match some_configuration with .... in
timer fun_to_test arg
这个选择的问题是,一开始看起来很好,在添加了一些选项之后,您会遇到一种情况,即要测试的不同函数的参数不属于同一类型。您有一个类型错误。错误代码示例:
通过使用预先传递的参数强制闭包,我可以在这里免费获得“存在类型”:最后一个函数参数的类型不会出现在timer
应用程序的类型中。我发现这在实践中更好
当然,您也可以延迟整个调用,并在pad的设计中使用
()
作为参数。但我更喜欢一个迫使我这么做的选择,因为否则我太想不这么做了,我以后再付钱。如果你知道函数在部分应用时没有做任何有趣的事情(像大多数函数一样),那么你甚至不需要抽象。只要调用定时器(gx1x2…xN-1)xN
@AndreasRossberg:谢谢,我把你的观点纳入了我的答案中。
let fun_to_test, arg = match some_configuration with .... in
timer fun_to_test arg
let fun_to_test, arg =
if Random.bool ()
then (foo, 3)
else (bar, 3.2)
in timer fun_to_test arg