2015-04-14 55 views
6

在F#中,您可以對函數簽名進行模式匹配。我想用一個函數來裝飾許多函數,這個函數測量函數的執行並調用statsd。目前的功能我已經是:基於函數簽名的模式匹配

let WrapFunctionWithPrefix(metrics:Metric.Client.IRecorder, functionToWrap, prefix) = 
    let metricsIdentifier = (sprintf "%s.%s" prefix Environment.MachineName) 
    using (metrics.StartTimer(metricsIdentifier)) (fun metrics -> functionToWrap) 

正如你可以在上面看到,前綴會有所不同,並且在我們的應用程序,這將每個函數的定義有所不同。因此,不應在測量前綴我想要做類似下面的每一次傳遞:

let WrapFunction metrics afunc = 
    match afunc with 
    | :? (int -> int) -> WrapFunctionWithPrefix(metrics, afunc, "My function 1") 
    | :? (string -> string) -> WrapFunctionWithPrefix(metrics, afunc, "My function 2") 
    | _ -> failwith "Unknown function def" 

有模式的任何方式匹配基於在F#函數簽名?

任何幫助表示讚賞。

比利

回答

7

是否可以將案例申報爲DU?

type MyFunctions = 
| Intish of int -> int 
| Stringish of string -> string 
+0

乾杯,順着這條路走下去了。稍微優雅! – bstack

3
let WrapFunction metrics afunc = 
    match box afunc with 
    | :? (int -> int) -> WrapFunctionWithPrefix(metrics, afunc, "My function 1") 
    | :? (string -> string) -> WrapFunctionWithPrefix(metrics, afunc, "My function 2") 
    | _ -> failwith "Unknown function def" 

會爲你的模式匹配工作。在嘗試投射它們之前,通常最終需要使用box未知類型,如下所示:?不喜歡在值類型上使用。

我不完全確定您的使用語句將如何與您返回的函數進行交互。我認爲它會立即處置度量並返回函數,這可能不是你想要的。

+3

另外請注意,在你的''afunc''參數中你完全沒有類型安全性。如果有人想傳入不是函數的東西,編譯器不會阻止它們。 – mavnn