Сопоставление с образцом на основе сигнатуры функции

В 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#?

Любая помощь приветствуется.

Билли


person bstack    schedule 14.04.2015    source источник


Ответы (2)


Можно ли объявить случаи как DU?

type MyFunctions =
| Intish of int -> int
| Stringish of string -> string
person Daniel Fabian    schedule 14.04.2015
comment
Ура, пошел по этому пути и работал. Чуть элегантнее! - person bstack; 14.04.2015

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 неизвестных типов, прежде чем пытаться их преобразовать, как :? не любит использоваться в типах значений.

Я не совсем уверен, как ваш оператор using будет взаимодействовать с функцией, которую вы возвращаете. Я думаю, что он будет удалять метрики и немедленно возвращать функцию, что, вероятно, не то, что вам нужно.

person mavnn    schedule 14.04.2015
comment
Также обратите внимание, что вы вообще не получаете безопасность типов для вашего параметра afunc. Если кто-то хочет передать что-то, что не является функцией, компилятор не остановит его. - person mavnn; 14.04.2015