KeyExistsQ[] but for functions?
DownValues
aren't the only method for caching previously computed results. For instance you can use an association,
ClearAll[fdata, f]
fdata = <||>;
f[x_] := Lookup[fdata, x, fdata[x] = x^2]
Now when you compute a value it is stored in fdata
,
In[21]:= f /@ Range[3]
Out[21]= {1, 4, 9}
In[22]:= KeyExistsQ[fdata, #] & /@ Range[4]
Out[22]= {True, True, True, False}
Here's a simple method for checking if any of the down values of a function matches f[5]
literally. It's a good use case for Verbatim
:
KeyExistsForFunctionsQ[fun_, arg_] := AnyTrue[
Keys[DownValues[fun]],
MatchQ[#, Verbatim[HoldPattern[fun[arg]]]] &
]
This method can be extended to checking other types of down values of functions as well. For example:
ValueQWithoutEval[fun_, arg_] := AnyTrue[
Keys[DownValues[fun]],
MatchQ[Hold[fun[arg]], Hold[#]] &
]
This will check if any of the down values of a function will match fun[arg]
without actually trying to evaluate it (because it might be expensive, for example). Note that this will not work for assignments that use Condition
in the r.h.s. of :=
like
f[x_] := With[{y = 2 x + 1}, y /; PrimeQ[y]]
For functions like that, you can't avoid evaluating the function at least partially to find out if the argument matches.