【问题标题】:Using nested slots (#)使用嵌套插槽 (#)
【发布时间】:2011-02-07 10:28:40
【问题描述】:

假设我想构建类似的东西

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

现在我想用一个变量替换“3”。我可以这样做,例如:

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

问题是:有没有办法使用 only 插槽和 & 作为功能符号?

【问题讨论】:

  • 这让我查看了Slot (+1) 的文档。阶乘的递归纯函数定义:f = If[#1 == 1, 1, #1 #0[#1 - 1]]& 非常漂亮!
  • @Simon 是的。那 #0 也让我担心:D
  • @Simon,我以前从未仔细阅读过 Slot 文档。 #0 确实很麻烦,而且可能非常有用。
  • @belisarius 解决方案是否必须使用Array?我觉得Table这个功能可以满足你现在的需求吗?
  • @dbjohn 例如等价于f[x_] := Sort[x, #1 > #2 Last@x &]f[{7, 3, 2}]={7,2,3}

标签: wolfram-mathematica


【解决方案1】:

不是原来问题的真正答案,但我注意到很多人对#0 的东西感兴趣,所以here 我放了几个不平凡的例子,希望它们有用。

关于嵌套函数应该使用带命名参数的函数的声明:虽然这通常是正确的,但应该始终牢记纯函数(通常)的词法作用域在 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]

这种行为与规则替换的侵入性有关 - 也就是说,RuleRuleDelayed 不关心可能出现在表达式主题中的范围构造中的名称之间可能的名称冲突规则应用程序,以及规则中模式变量的名称。更糟糕的是,gf 在单独使用时完全可以正常工作。正是当它们混合在一起时,才会发生这种纠缠,只是因为我们不幸在f 的主体中使用了相同的模式变量x,就像在纯函数中一样。这使得此类错误很难被发现,而在实践中有时确实会发生这种情况,因此我建议不要将带有命名参数的纯函数作为参数传递给通过模式定义的高阶函数。

编辑:

对词法作用域的模拟进行了一些扩展。我的意思是,例如,当我创建一个纯函数(这是一个词法范围构造,将其主体中的变量名绑定到传递的参数的值)时,我希望我不能改变这个绑定在我创建了一个函数之后。这意味着,无论我在哪里使用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 在this 页面的帖子底部也注意到了这种行为——显然他也有类似的经历。基于对 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]

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

【讨论】:

  • @Leonid 感谢您的精彩解释和示例。我认为这个stackoverflow.com/questions/4198961/… 是一个发布它的好地方,也许你也可以在那里贡献其他想法。
  • @belisarius 谢谢,我不知道把这样的东西放在哪里。您认为将这篇文章重新定位到那里并从这里链接到它是一个好主意吗?如果是,我该如何重新定位帖子 - 我应该在这里删除它并在那里发布吗?
  • @Leonid 我想你可以把它贴在那里,然后在这里留下一个答案,基本上是第一段和指向另一个答案的指针。我(希望是“我们”)想在 toolbag 中收集有用的食谱和澄清概念。我相信你可以帮上大忙!另请注意,在我们正在收集索引的问题中,如果您已经拥有编辑权限,请随时更新索引,或者如果您仍然不能,我们将为您执行此操作。
  • @belisarius 感谢您的解释 - 为帖子完成。至于索引 - 你的意思是页面顶部的书籍列表等,对吗? - 我很快会贡献一些条目。
  • @Leonid 1) 太好了! 2)是的,我的意思是那个索引。 3) 您能否进一步解释模拟词法作用域
【解决方案2】:

怎么样

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

非常丑陋的元素提取,非常有趣的是Map[Last, #]& 给了我与Last /@ 不同的结果。这是因为Map&的属性不同吗?

【讨论】:

  • 地图[Last, #] & /@ === (Last /@ #) & /@ != Last /@
【解决方案3】:

我想您知道文档中关于 nested pure functions 的内容。

使用显式名称设置嵌套 纯函数(例如):

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}]]

【讨论】:

  • 是的,我知道文档:D。尽管如此,在这种情况下,我想为内部和外部参数使用相同的变量值似乎容易受到一些黑客攻击。
  • @belisarius:实际上,我没有注意到是你提出了这个问题。对不起!
  • 下次我会添加一个nice portrait 以方便识别:D
【解决方案4】:

With[{x = #1}, Array[#1^#2 == x &, {x, x}]] &怎么样?

【讨论】:

  • +1。是的,这是可能性之一。实际上,当我需要嵌套基于槽的函数时,我经常使用这种结构,而且我知道其他一些人也在使用它。
  • 命名参数在某种程度上是必要的。好吧,匿名函数在面对嵌套构造时有局限性。对我新手来说是个好教训!
  • Sequence[x, Array[#1^#2 == x &, {x, x}]] &也是一种技能。
【解决方案5】:

也许

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

或者

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

【讨论】:

  • @belisarius 谢谢。 :-) 很高兴像我这样的菜鸟有任何东西可以提供一个 13.7K 代表的大师。
  • 您经常会在这里看到由很少有代表点的人发布的精彩问题和答案。不要被这些数字所迷惑,您会发现用户对 Mma 的了解程度很高,而代表则低得多。顺便说一句:欢迎!
  • @belisarius 看,我现在有 13.7K 代表。 :-)
  • :D 正如我所说:不要被数字所迷惑 :DD 恭喜!
猜你喜欢
  • 2019-06-08
  • 2018-08-09
  • 2018-07-28
  • 2019-04-25
  • 2020-05-19
  • 2022-09-29
  • 2023-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多