Como definir um parâmetro com Optional e PatternTest

Aug 30 2020

Por que isso não funciona?

k[x_Integer:2?(#>0&)]:=x^2
k[]  (*should be 4*)
k[2] (*should be 4*)

Estes a seguir estão todos funcionando conforme o esperado:

(* with Optional *)
f[x_Integer:2]:=x^2
f[]
(* with PatternTest *)
g[x_Integer?(#>0&)]:=x^2
g[2]
(* with Optional + Condition *)
h[x_Integer:2]:=x^2/;x>0
h[]
h[2]

Respostas

1 m_goldberg Aug 30 2020 at 22:22

Não funciona porque :pode ter dois significados em uma forma de argumento, Optionale Pattern, e o front-end tem problemas para decidir qual é o significado quando dois :aparecem em tal argumento.

Você pode corrigir o problema escrevendo Optionalna forma completa. Igual a:

Clear[k]; k[Optional[x_Integer?Positive, 2]] := x^2; {k[], k[2], k[-2], k[2.]

{4, 4, k[-2], k[2.]}

Você também pode querer considerar algumas alternativas.

Clear[k]; k[x_Integer : 2] /; x > 0 := x^2  
Clear[k]; k[x_ : 2] /; x ∈ PositiveIntegers := x^2
Clear[k]; Default[k] = 2; k[x_.] /; x ∈ PositiveIntegers := x^2