使用嵌套插槽(#)

Dr.*_*ius 12 wolfram-mathematica

假设我想构建类似的东西

Array[#1^#2 == 3 &, {3, 3}] 
Run Code Online (Sandbox Code Playgroud)

现在我想用变量替换"3".我可以做,例如:

f[x_] := Array[#1^#2 == x &, {x, x}]  
Run Code Online (Sandbox Code Playgroud)

问题是:是否有一种方法使用插槽和&作为功能表示法?

Leo*_*rin 9

不是原来问题的答案,但我注意到很多人都对#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]
Run Code Online (Sandbox Code Playgroud)

这种行为已经做规则替代的侵入性-也就是说,用事实RuleRuleDelayed不关心在划定范围可能存在于受到规则的应用程序表达构造名之间可能的名称冲突,以及模式变量的名字在规则中.更为糟糕的是,gf当它们分开工作完全没问题.当它们混合在一起时,就会发生这种纠缠,只是因为我们不幸x在身体中使用相同的模式变量f,就像在纯函数中一样.这使得这些错误很难捕获,而这种情况有时会在实践中发生,所以我建议不要将带有命名参数的纯函数作为参数传递给通过模式定义的高阶函数.

编辑:

在模拟词法范围方面进行了一些扩展.我的意思是,例如,当我创建一个纯函数(它是一个词法范围构造,将其体内的变量名称绑定到传递参数的值)时,我希望我不能改变这个绑定在我创建了一个函数之后.这意味着,无论我在哪里使用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]
Run Code Online (Sandbox Code Playgroud)

或者,甚至更简单(我之前警告的本质):

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]
Run Code Online (Sandbox Code Playgroud)

我被这最后一次行为咬了几次非常痛苦.这种行为也被@WReach在他的文章底部注意到这个页面-显然他有类似的经历.根据Mathematica在冲突期间如何重命名变量的确切知识,还有其他方法可以打破范围,但这些方法在实践中的危害相对较小.一般来说,如果坚持Mathematica表达式所代表的透明度,我不认为可以避免这些事情.它似乎对于纯函数(通常是词法作用域结构)来说是"过度透明",但另一方面它也有它的用途,例如我们可以在运行时伪造一个纯函数,如下所示:

In[82]:= Block[{x},Function@@{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]
Run Code Online (Sandbox Code Playgroud)

积分只在定义时计算一次(也可以使用Evaluate).所以,这看起来像是一种权衡.通过这种方式,功能抽象可以更好地集成到Mathematica中,但是正如@WReach所指出的那样是漏洞.或者,它可能是"防水的",但也许是为了减少暴露的代价.这显然是一个设计决定.


Tim*_*imo 4

怎么样

Map[Last, #] & /@ Array[#1^#2 == #3 &, {#, #, #}] &[3]
Run Code Online (Sandbox Code Playgroud)

元素提取极其丑陋,并且非常有趣地Map[Last, #]&给了我一个与Last /@. 这是因为Map具有不同的属性吗&

  • 地图[最后,#] & /@ === (最后 /@ #) & /@ != 最后 /@ (2认同)