Say I have a recursive function that I want to know how many times the function has called itself per input value. Rather than putting printf expressions or changing the return type to include the number of calls, is it possible to “wrap” the function with another to achive this? I would like the wrapped function to return the number of function calls and the original functions result. It should be reusable across different functions.
Here is what I have and it doesn’t work.
open System
open System.IO
open System.Collections.Generic
/// example recursive function
let rec getfilenames dir =
seq {
yield Directory.GetFiles dir
for x in Directory.GetDirectories dir do yield! getfilenames x}
/// function to count the number of calls a recursive function makes to itself
let wrapped (f: 'a -> 'b) =
let d = new Dictionary<'a, int>()
fun x ->
let ok, res = d.TryGetValue(x)
if ok then d.[x] <- d.[x] + 1
else
d.Add(x, 1)
d, f x
> let f = wrapped getfilenames
let calls, res = f "c:\\temp";;
val f : (string -> Dictionary<string,int> * seq<string []>)
val res : seq<string []>
val calls : Dictionary<string,int> = dict [("c:\temp", 1)]
This is not going to work, because
getfilenamesis defined as callinggetfilenames, not any other function and especially not a function defined after that. So, as soon as your wrapper calls the function, the function will ignore your wrapper and start calling itself.What you need to do is move the recursion out of the
getfilenamesfunction and into another function, by providing the function to be called recursively as a parameter.Now, you can wrap
bodybefore plugging it into a recursive function:Note that the
wrapfunction returns both the wrapped function (with a signature identical to the original function) and the dictionary, for external access. The number of calls will then be found incalls.