2010-09-17 75 views
5

功能FunctionQ將如何看起來,也許我甚至可以指定允許的參數數量?測試表達式是否爲函數?

+0

我不太明白你的問題。你的意思是你想寫一個FunctionQ [input_]函數,如果輸入是一個函數,返回True,否則返回false?輸入採取什麼形式? – 2010-09-17 16:20:25

+0

@Mark:我會回答是的第一個問題。輸入的形式是一個Mathematica表達式... – 2010-09-17 20:18:47

回答

10

西蒙和丹尼爾之後,我真的覺得不舒服,但是他們的代碼在非函數上失敗,而這些函數不是符號。檢查這一點,通過NumericFunction增加了內建的支票,由西蒙的建議,我們得出類似

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

應在一些(嘆氣)真實世界的情況下工作

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} 

如果您知道你正在尋找的函數的簽名(即多少個參數和什麼類型),我會同意西蒙的說法,那就是鴨子打字:Apply這個函數用於典型的參數,並尋找有效的輸出。緩存可能是值得的:

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} 
+0

絕對不會感覺不好!這就是SO的MO:相互建立,以提出最佳答案。對此,偉大的工作,順便說一句! – dreeves 2010-09-23 12:43:06

+0

我只是再看一遍,我注意到'FunctionQ'沒有被'AlternativeFunctionQ'發現爲1 var函數。因此,儘管它在找到數字函數方面很有效,但它找不到其他類型。 – rcollyer 2010-11-05 19:54:04

+0

@rcollyer:'AlternativeFunctionQ'就是一個例子:典型的參數以及有效的輸出應該適應當前的情況。我想這從架構的角度來看並不是很優雅,但它通常很適合這項法案。 – Janus 2010-11-08 02:04:07

2

這裏的東西快速和骯髒的可以做你的需要:

FunctionQ[x_] := Head[x] == Function || DownValues[x] =!= {} 
+0

謝謝!我試着在星期一接受你的答案,然後...... – 2010-09-17 20:19:23

3

正如丹尼爾說,他的測試(這可能應該讀)

FunctionQ[x_] := Head[x] === Function || DownValues[x] =!= {} 

是快速和骯髒。內置函數會失敗,例如FunctionQ[Sin]將返回False(通過檢查AttributeNumericFunction將捕獲許多內置函數)。它也將失敗,如f[x_][y_]等......它也許應該測試UpValues,SubValuesNValues(參見here的含義)。

此問題在此thread中討論過。在這個主題中有許多有用的想法 - 例如找出一些函數可以採用的論證數量的方法,但是在討論中沒有達成真正的共識。

我認爲最好的方法是一種duck typing。你可能知道你想要你的函數有多少種類型的參數,所以用ValueQ進行測試。然後確保您使用Check發現錯誤。

編輯: 另一個comp.soft-sys.math.mathematica thread