Проверить, является ли выражение функцией? - PullRequest
5 голосов
/ 17 сентября 2010

Как бы выглядела функция FunctionQ, может быть, я даже могу указать количество допустимых аргументов?

Ответы [ 3 ]

11 голосов
/ 20 сентября 2010

Я действительно плохо пишу после Саймона и Даниэля, но их коды не работают на не-функциях, которые не являются символами. Проверяя это и добавляя проверку на встроенные через 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} 
3 голосов
/ 18 сентября 2010

Как сказал Даниил, его тест (который, вероятно, следует прочитать)

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

Быстро и грязно. Это не удастся для встроенных функций, например FunctionQ[Sin] вернет False (многие встроенные функции будут перехвачены при проверке на Attribute NumericFunction). Он также потерпит неудачу для таких вещей, как f[x_][y_] и т.д. ... Вероятно, он также должен проверить UpValues, SubValues и, возможно, NValues (см. здесь для их значений).

Эта проблема обсуждалась в этой теме . В этой ветке много полезных идей - например, способы определения количества аргументов, которые могут принимать некоторые функции, но в ходе обсуждения не было достигнуто реального консенсуса.

Я думаю, что лучше всего подойдет утка, набравшая . Вы, вероятно, знаете, сколько и какой тип аргументов вы хотите, чтобы ваша функция принимала, поэтому протестируйте ее с помощью ValueQ . Затем убедитесь, что вы ловите ошибки, используя Check .

EDIT: Другой comp.soft-sys.math.mathematica поток .

2 голосов
/ 18 сентября 2010

Вот что-то быстрое и грязное, которое может сделать то, что вам нужно:

FunctionQ[x_] := Head[x] == Function || DownValues[x] =!= {}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...