Estou tentando reproduzir a API de uma função (escrita em R) que aceita um número arbitrário de argumentos e o trata da mesma maneira que faria com um único argumento que é uma lista de conjuntos de dados diferentes.
Existe um idioma do Mathematica que permite que uma função seja definida para que:
f[ arg1, arg2, ..., argN ]
se comporte o mesmo que
f[ {arg1, arg2, ..., argN} ]
?
Comentários
Resposta
Conforme descrito por Andy Ross em um comentário, você pode fazer uma definição que pré-processe o (s) argumento (s) em uma forma canônica. Virando seu exemplo simplesmente para ilustrar a flexibilidade:
f[{args__}] := f[args] f[args__] := Multinomial[args] / Plus[args] f[{12, 7, 3}] == f[12, 7, 3]
Verdadeiro
Este método é útil para um pré-processamento mais complicado, mas em casos simples como este, geralmente é mais fácil de usar Alternatives
:
g[{args__} | args__] := Multinomial[args]/Plus[args] g[{12, 7, 3}] == g[12, 7, 3]
Verdadeiro
Esteja ciente de que quando usando Alternatives
você deve ordenar manualmente os padrões, pois eles são testados em sequência. O padrão args__ | {args__}
não funcionaria como desejado porque args__
corresponderá a {12, 7, 3}
como um único argumento .
Resposta
Existem muitas maneiras de lidar com isso. A abordagem que eu provavelmente faria pode ser ilustrada pelo seguinte exemplo:
f[seqn : ___] := Module[{args = {seqn}}, Switch[args, {{___}}, "List of args", {_}, "One arg", {_, __}, "Two or more args", {}, "No args" ]] f[{x, y, z}] (* ==> "List of args" *) f[{x}] (* ==> "List of args" *) f[] (* ==> "No args" *) f[x] (* ==> "One arg" *) f[x, y, z] (* ==> "Two or more args" *)
Claro, cada aplicação desta técnica substituiria as strings vistas aqui por alguns ação apropriada às suas próprias necessidades.
Outra abordagem é escrever funções separadas para cada padrão de argumento que você deseja manipular:
g[args : {___}] := "List of args" g[] := "No args" g[arg_] := "One arg" g[arg_, rest__] := "Two or more args" g[{x, y, z}] (* ==> "List of args" *) g[{x}] (* ==> "List of args" *) g[] (* ==> "No args" *) g[x] (* ==> "One arg" *) g[x, y, z] (* ==> "Two or more args" *)
Comentários
- Qual é o seu raciocínio para " provavelmente " usando
Switch
em várias definições?Switch
geralmente é mais lento e não deve ser usado sem motivo, IMHO. - @ Mr.Wizard. Usar
Switch
apela ao meu senso de estética de programação porque organiza todas as alternativas para que possam ser tratadas em uma única função. Eu ' m geralmente não me preocupo muito com a velocidade de execução – não até que a execução lenta se torne realmente evidente.
f[args___]:= f[{args}]
e, em seguida, forneça a definição paraf[{arg1_, arg2_,...}]
.