2010-09-17 16 views
5

Jak mogłaby wyglądać funkcja FunctionQ, może w sposób, w jaki mogę określić liczbę dozwolonych argumentów?Sprawdź, czy wyrażenie jest funkcją?

+0

Nie bardzo rozumiem twoje pytanie. Czy masz na myśli, że chcesz napisać funkcję FunctionQ [input_], która zwraca True, jeśli input jest funkcją, false inaczej? Jaka forma przyjmuje dane wejściowe? –

+0

@ Mark: Pierwsze pytanie, na które odpowiedziałbym Tak. Forma, którą wprowadziłby dane wejściowe, to wyrażenie Mathematica ... –

Odpowiedz

10

Naprawdę źle się czuję po Simonie i Danielu, ale ich kody zawodzą w przypadku niedziałania, które nie są symbolami. Sprawdzanie że i dodanie czek na builtins poprzez NumericFunction, jak sugeruje Simon, dojeżdżamy na coś jak

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

które powinny działać w niektórych (westchnienie) przypadków rzeczywistych

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} 

Jeśli znać podpis funkcji, której szukasz (tj. ile argumentów i jakiego typu), zgodziłbym się z Simonem, że sposobem na to jest wpisanie kaczki: Apply funkcja typowych argumentów i poszukiwanie prawidłowych wyników. Buforowanie może być opłacalne:

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

Zdecydowanie nie czuj się źle! To MO's SO: budujcie się wzajemnie, aby uzyskać najlepszą możliwą odpowiedź. Świetna robota! – dreeves

+0

Właśnie się nad tym zastanawiałem i zauważyłem, że 'FunctionQ' nie jest funkcją 1-var przez' AlternativeFunctionQ'. Tak więc, chociaż jest skuteczne w znajdowaniu funkcji numerycznych, nie może znaleźć innych typów. – rcollyer

+0

@rcollyer: Przykładem było 'AlternativeFunctionQ' Typowe argumenty, jak również poprawny wynik powinny być dostosowane do danego przypadku. Sądzę, że nie jest to bardzo elegancki z punktu widzenia architektury, ale często bardzo dobrze pasuje do rachunku. – Janus

2

Oto coś szybkie i brudne, które mogą robić to, czego potrzebujesz:

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

Dziękujemy! Próbuję w poniedziałek i akceptuję twoją odpowiedź wtedy ... –

3

Jak powiedział Daniel, jego badanie (które prawdopodobnie powinny czytać)

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

jest szybki i brudny. Nie powiedzie się dla wbudowanych funkcji, np. FunctionQ[Sin] zwróci wartość fałszu (wiele wbudowanych funkcji zostanie przechwyconych przez sprawdzenie, czy nie ma ona wartości AttributeNumericFunction). Będzie to również porażką dla takich rzeczy, jak f[x_][y_] itp. Powinien prawdopodobnie również przetestować UpValues, SubValues i może NValues (patrz here).

Ten problem omówiono w tej publikacji: thread. Wiele pożytecznych pomysłów znajduje się w tym wątku - np. Sposoby na znalezienie liczby argumentów, które mogą mieć niektóre funkcje, ale nie osiągnięto prawdziwego konsensusu w dyskusji.

Myślę, że najlepszym podejściem jest rodzaj duck typing. Prawdopodobnie wiesz, ile i jakie argumenty chcesz użyć, więc przetestuj je pod ValueQ. Następnie upewnij się, że złapałeś błędy za pomocą Check.

EDYTOWANIE: Kolejne comp.soft-sys.math.mathematica thread.