6

In F# can you pattern match on a function signature. I want to decorate a number of functions with a function that measures the execution of the function and calls out to statsd. The current function I have is:

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

As you can see above, the prefix will vary, and in our application this will vary per function definition. So rather than having to pass in the measure prefix every time I want to do something like the following:

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"

Is there any way of pattern matching based on the function signature in F#?

Any help appreciated.

Billy

bstack
  • 2,466
  • 3
  • 25
  • 38

2 Answers2

7

Would it be possible to declare the cases as a DU?

type MyFunctions =
| Intish of int -> int
| Stringish of string -> string
Daniel Fabian
  • 3,828
  • 2
  • 19
  • 28
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"

will work for your pattern match. You normally end up having to box unknown types before trying to cast them, as :? doesn't like being used on value types.

I'm not totally sure how your using statement will interact with the function you return though. I think it will dispose metrics and return the function immediately, which is probably not what you want.

mavnn
  • 9,101
  • 4
  • 34
  • 52
  • 3
    Also note that you get no type safety at all on your ``afunc`` parameter. If someone wants to pass in something that isn't a function, the compiler won't stop them. – mavnn Apr 14 '15 at 13:18