F# 将函数作为参数传递并重载它
我想对我的函数计时,其中一些函数最多使用三个参数。现在我正在使用下面相同的代码,并对这三个版本进行了一些修改F# 将函数作为参数传递并重载它,f#,parametric-polymorphism,F#,Parametric Polymorphism,我想对我的函数计时,其中一些函数最多使用三个参数。现在我正在使用下面相同的代码,并对这三个版本进行了一些修改 let GetTime f (args : string) = let sw = Stopwatch.StartNew() f (args) printfn "%s : %A" sw.Elapsed 我想用这个函数替换这三个函数 let GetTime f ( args : 'T[]) = let sW = Stopwatch.StartNew()
let GetTime f (args : string) =
let sw = Stopwatch.StartNew()
f (args)
printfn "%s : %A" sw.Elapsed
我想用这个函数替换这三个函数
let GetTime f ( args : 'T[]) =
let sW = Stopwatch.StartNew()
match args.Length with
| 1 -> f args.[0]
| 2 -> f (args.[0] args.[1])
printfn "%A" sW.Elapsed
()
但是如果我使用这三个函数,我会得到一个类型不匹配的错误。是否可以将函数作为参数发送并像这样使用它?您可能正在考虑将一个方法组作为参数传递给
GetTime
,然后让编译器决定调用方法组的哪个重载。这在任何.NET编译器中都是不可能的。方法组由编译器和工具(如ReSharper)用于代码分析,但它们在运行时并不实际存在。编译器不可能知道在运行时将传递多少个参数,因此函数f
必须同时满足't->unit
和't->unit
。此表单还要求所有参数的类型相同
let getTime f =
let sw = Stopwatch.StartNew()
let result = f ()
printfn "%A" sw.Elapsed
result
以下方法延迟函数执行,可能适合您的需要
let printTime f =
let sw = Stopwatch.StartNew()
f() |> ignore
printfn "%A" sw.Elapsed
let f1 s = String.length s
let f2 s c = String.concat c s
printTime (fun () -> f1 "Test")
printTime (fun () -> f2 [| "Test1"; "Test2" |] ",")
为什么不这样做呢
let getTime f =
let sw = Stopwatch.StartNew()
let result = f ()
printfn "%A" sw.Elapsed
result
假设f1
、f2
和f3
是分别采用1、2和3个参数的三个函数,您可以像这样使用getTime
函数:
getTime (fun () -> f1 "foo")
getTime (fun () -> f2 "foo" "bar")
getTime (fun () -> f3 "foo" "bar" "baz")
let f1Curried (s: string) (b: bool) =
System.Threading.Thread.Sleep 1000
s
let f2Curried (n: int) (s:string) (dt: System.DateTime) =
System.Threading.Thread.Sleep 1000
n+1
但是,如果您只需要对FSI中的某些函数计时,则此功能已经内置:只需键入
> #time;;
如果函数采用元组形式的参数,则会打开计时。,如下所示:
let f1 (s: string, b: bool) =
System.Threading.Thread.Sleep 1000
s
let f2 (n: int, s:string, dt: System.DateTime) =
System.Threading.Thread.Sleep 1000
n+1
那么实现就变得微不足道了:
let Timed f args =
let sw = System.Diagnostics.Stopwatch.StartNew()
let ret = f args
printfn "Called with arguments %A, elapsed %A" args sw.Elapsed
ret
用法:
f1
|> Timed // note, at this time we haven't yet applied any arguments
<| ("foo", true)
|> printfn "f1 done, returned %A"
f2
|> Timed
<| (42, "bar", DateTime.Now)
|> printfn "f2 done, returned %A"
这变得有点棘手。这个想法是使用标准运算符
(为什么你不能在成员
函数上使用多态性呢?我只是想在模块中保持简单。我正在尝试一种功能性更强的方法,没有类型。我知道F#是多半径的,但我想尝试其他方法。请注意,你的问题与运算符重载无关。你描述的是param计量多态性。