Использование вложенных слотов (#)

Предположим, что я хочу построить что-то вроде

Array[#1^#2 == 3 &, {3, 3}] 

И теперь я хочу заменить "3" на переменную. Я могу сделать, например:

f[x_] := Array[#1^#2 == x &, {x, x}]  

Вопрос: есть ли способ использовать только слоты и как функциональную нотацию?

Ответ 1

Как насчет

Map[Last, #] & /@ Array[#1^#2 == #3 &, {#, #, #}] &[3]

Ужасно уродливое извлечение элементов, и очень интересно Map[Last, #]& дает мне отличный результат, чем Last /@. Это связано с тем, что Map имеет разные атрибуты, чем &?

Ответ 2

Не совсем ответ на исходный вопрос, но я заметил, что многие люди интересовались вещами #0, поэтому здесь Я поставил пару нетривиальных примеры, надеюсь, что они будут полезны.

Что касается утверждения о том, что для вложенных функций следует использовать функции с именованными аргументами: в то время как это обычно верно, всегда следует помнить, что лексическое определение чисто функций (и вообще) эмулируется в Mathematica и может быть нарушено. Пример:

In[71]:= 
Clear[f,g];
f[fun_,val_]:=val/.x_:>fun[x];
g[fn_,val_]:=f[Function[{x},fn[#1^#2==x&,{x,x}]],val];
g[Array,3]

During evaluation of In[71]:= Function::flpar: Parameter specification {3} in  
   Function[{3},Array[#1^#2==3&,{3,3}]] should be a symbol or a list of symbols. >>
During evaluation of In[71]:= Function::flpar: Parameter specification {3} in 
   Function[{3},Array[#1^#2==3&,{3,3}]] should be a symbol or a list of symbols. >>

Out[74]= Function[{3},Array[#1^#2==3&,{3,3}]][3]

Это поведение связано с интрузивным характером подстановок правил, т.е. с тем, что Rule и RuleDelayed не заботятся о возможных столкновениях имен между именами в конструкциях оглавления, которые могут присутствовать в выражениях subject для управления приложениями и имен переменных шаблонов в правилах. Хуже всего то, что g и f работают отлично, если брать отдельно. Когда они смешиваются, это происходит, и только потому, что нам не повезло использовать одну и ту же переменную шаблона x в теле f, как в чистой функции. Это приводит к тому, что такие ошибки очень трудно поймать, в то время как такие ситуации случаются иногда на практике, поэтому я бы рекомендовал не передавать чистые функции с именованными аргументами в качестве параметров в функции более высокого порядка, определенные через шаблоны.

Edit:

Развертывание бит для эмуляции лексического охвата. Я имею в виду, например, когда я создаю чистую функцию (которая представляет собой конструкцию лексического охвата, которая связывает имена переменных в своем теле с значениями переданных параметров), я ожидаю, что я не смогу изменить эту привязку после того, как я создал функцию. Это означает, что независимо от того, где я использую Function[x,body-that-depends-on-x], я должен иметь возможность рассматривать его как черный ящик с входными параметрами и результирующими выходами. Но в Mathematica Function[x,x^2] (например) также является выражением и как таковое может быть изменено, как и любое другое выражение. Например:

In[75]:= 
x = 5;
Function[Evaluate[x],x^2]

During evaluation of In[75]:= Function::flpar: Parameter specification 5 in Function[5,x^2] should 
  be a symbol or a list of symbols. >>
Out[76]= Function[5,x^2]

или, что еще проще (суть моего предыдущего предупреждения):

In[79]:= 1/.x_:>Function[x,x^2]

During evaluation of In[79]:= Function::flpar: Parameter specification 1 in Function[1,1^2] should 
  be a symbol or a list of symbols. >>

Out[79]= Function[1,1^2]

Я был укушен этим последним поведением несколько раз довольно болезненно. Это поведение также отметили @WReach в нижней части своего сообщения на этой странице - очевидно, что у него были подобные впечатления. Существуют и другие способы нарушения масштаба, основанные на точном знании того, как Mathematica переименовывает переменные во время конфликтов, но на практике они сравнительно менее вредны. Как правило, я не думаю, что такого рода вещи можно избежать, если вы настаиваете на уровне прозрачности, представленном выражениями Mathematica. Это просто кажется "чрезмерно прозрачным" для чистых функций (и вообще лексических схем), но, с другой стороны, это также имеет свои применения, например, мы можем создать чистую функцию во время выполнения следующим образом:

In[82]:= Block[{x},[email protected]@{x,Integrate[HermiteH[10,y],{y,0,x}]}]

Out[82]= Function[x,-30240 x+100800 x^3-80640 x^5+23040 x^7-2560 x^9+(1024 x^11)/11]

Если интеграл вычисляется только один раз, во время определения (может также использовать Evaluate). Таким образом, это выглядит как компромисс. Таким образом, функциональная абстракция лучше интегрирована в Mathematica, но протекает, как заметил @WReach. В качестве альтернативы он мог бы быть "водонепроницаемым", но, возможно, ценой менее подверженной воздействию. Это было явно конструктивное решение.

Ответ 3

Я думаю, вы знаете, что в документации говорится о вложенных чистых функциях.

Использовать явные имена для настройки вложенных чистые функции (например):

Function[u, Function[v, f[u, v]]][x]

В любом случае, здесь лучшее, что я мог придумать, не следуя приведенному выше совету:

f[x_] := Array[#1^#2 == x &, {x, x}]
g = Array[With[{x = #}, #1^#2 == x &], {#, #}] &

g функционально идентичен исходному f, но на самом деле не лучше рекомендуемого

h = Function[x, Array[#1^#2 == x &, {x, x}]]

Ответ 4

Как насчет With[{x = #1}, Array[#1^#2 == x &, {x, x}]] &?

Ответ 5

Может

Array[#1^#2 &, {#, #}] /. i_Integer :> i == # &[3]

или

Thread /@ Thread[# == Array[#1^#2 &, {#, #}]] &[3]