在APL中将函数作为参数传递

5

我如何将函数作为参数传递?

基本思路如下(不起作用):

∇R ← double a
R ← 2 × a
∇

∇R ← a applytwice f
R ← f f a
∇

5 applytwice double

在Erlang中是否有类似于\fun的东西或者在C语言中是否有函数指针?

4个回答

9
在APL中,函数不能作为参数传递给其他函数。不过,APL有一些运算符,它们是高阶函数,可以接受函数作为参数。例如,原始运算符 /(约简)用于对向量求和 +/v。函数+是左操作数,并被传递到运算符/中。
在Dyalog APL中,有一个名为“power”的原始运算符,用于重复应用一个函数n次,因此我们可以编写:
      double←{2×⍵}
      (double2) 7
28
      (double10) 7
7168

在大多数 APL 中,您也可以编写自己的运算符。在 Dyalog APL 中,我们可以将 applytwice 运算符编写为:

     applytwice←{⍺⍺ ⍺⍺ ⍵}
     double applytwice 7
28

最后,您可以将函数放入名称空间中,并传递名称空间而不是函数本身。这类似于具有方法的非常轻量级的类实例。例如:

       s←⎕NS ''
       s.f←{2×⍵}
       ApplyFTwice←{⍺.f ⍺.f ⍵}
       s ApplyFTwice 7
28

在这种情况下,函数必须被命名为f,但我们可以有许多不同的函数被命名为f,在它们各自的命名空间中。

感谢您详尽的回答,我已经弄清楚了如何在GNU APL中定义运算符(只需添加一些括号)。看起来在APL中,运算符和函数有严格的区分,“运算符”指的是函数子。 - Hyperboreus

5

你的 applytwice 并没有离正确答案太远。在 Dyalog APL 和其他一些语言中,非 dfn(传统函数定义)代码可能如下所示:

       ∇ R ← (f applytwice) a
  [1]   R ← f f a
       ∇

       - applytwice 42
  42

       {2×⍵} applytwice 42
  168

在APL中,任何接受零、一个或两个数据参数的“程序”都是“函数”。内置函数(例如+ -等)可能被称为“原始函数”。示例中的double函数将是“定义函数”。 “运算符”接受函数和数据作为参数。+/和+\是约简和扫描运算符的示例,+是/或\运算符的函数左参数。相比之下,压缩和展开函数使用相同的符号(/和\),但具有左侧数据参数。
这就是APL的命名方式。

1
你知道遗留的高阶函数的二元形式吗? - cannadayr
2
∇ R ← a (f higher g) b // 这个概念与数据和函数都有关的二元操作符。像这样调用:42 (+ higher -) 13 - Lobachevsky

0
不要直接传递它,而是将一个函数的QUAD CR作为参数传递,然后在调用函数内部进行QUAD FX操作。

0

你也可以通过引用来避免这个问题。你可以传递一个字符数组,然后在函数内执行它。该字符串可能包含已定义函数的名称或直接定义。


一个好的解决方案,几乎适用于所有的APL实现,从IBM APL.SV(约1970年)到现在。APL\360(1968年)没有execute,但是之后的所有版本都有。 - Lobachevsky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接