Test if an expression is a Function?

后端 未结 3 1199
不思量自难忘°
不思量自难忘° 2021-01-03 01:16

How would a function FunctionQ look like, maybe in a way I can even specify the number of arguments allowed?

3条回答
  •  长情又很酷
    2021-01-03 01:40

    I really feel bad posting after Simon and Daniel, but their codes fail on non-functions which are not symbols. Checking for that and adding a check for builtins via NumericFunction, as suggested by Simon, we arrive at something like

    FunctionQ[_Function | _InterpolatingFunction | _CompiledFunction] = True;
    FunctionQ[f_Symbol] := Or[
      DownValues[f] =!= {}, 
      MemberQ[ Attributes[f], NumericFunction ]]
    FunctionQ[_] = False;
    

    which should work in some (sigh) real-world cases

    In[17]:= 
    FunctionQ/@{Sin,Function[x,3x], Compile[x,3 x],Interpolation[Range[5]],FunctionQ,3x,"a string", 5}
    Out[17]= {True,True,True,True,True,False,False,False}
    

    If you know the signature of the function you are looking for (i.e. how many arguments and of what type), I would agree with Simon that the way to go is duck typing: Apply the function to typical arguments, and look for valid output. Caching might be worthwhile:

    AlternativeFunctionQ[f_]:=AlternativeFunctionQ[f]=
      With[{TypicalArgs={1.0}},NumericQ[Apply[f,TypicalArgs]]];
    
    In[33]= AlternativeFunctionQ/@{Sin,Function[x,3x], Compile[x, 3x],Interpolation[Range[5]],FunctionQ,3x,"a string", 5}
    Out[34]= {True,True,True,True,False,False,False,False} 
    

提交回复
热议问题