我想定义一个带有单个参数的匿名函数向量,然后在这个向量中映射一个参数x
,为每个索引返回f(x)
结果的数组。 Dyalog有可能吗?
我问,因为我天真地尝试创建这样的闭包矢量:
fs ← {⍵×2} {⍵×4} {⍵×8}
表现得很奇怪。试图引用fs
的单个索引似乎引用了所有这些索引并使输出变得混乱:
fs[1]
∇{⍵×2}
∇ ∇{⍵×4}
∇ ∇{⍵×8}
∇ [ 1
⍴fs
返回类似的输出而不是3,让我相信我根本没有制作数组。什么是正确的方法呢?
答案 0 :(得分:4)
不幸的是,这在Dyalog中是不可能的。你所做的确实没有一个数组fgh-fork,它是一系列函数f g h
,当它们像(f g h)Y
一样被称为(f Y)g h Y
时,表现得像[
。如果左括号(/
)的确切左侧有一个函数而不是数组,那么这不是括号内的索引,而是axis operator。但是,轴运算符只能应用于某些基本函数,以及从\
,⌿
,⍀
或⍴fs
派生的函数,因此它将是SYNTAX ERROR适用于你的功能。
fs
再次是一个函数序列,在这种情况下是一个顶点,而不会返回fs
的形状,因为FL
是一个函数。
但是,即使函数不是APL中的第一类对象,您也可以以某种方式滥用列车,使其看起来像参数实际映射到一组函数中。为此,我们定义一个“ F 指示链 L 墨水”函数FL ← {(⊂⍺),⍵}
:
f
所以,假设我们如何使用函数g
,h
,Y
和参数(f Y)(g Y)(h Y)
,我们想要返回(f FL g FL h)Y
。这现在可以写成FL
,对吗?好吧,不,有一个问题。必须使用FL∘⊂
替换最右侧出现的Y
。不幸的是,这是一个不可避免的麻烦,但至少现在你每次都可以免于提及f
。现在有两种情况:
(⊂f)Y
:在这种情况下,您只需使用f
。g
,h
和(f FL g FL∘⊂h)Y
:现在,您将编写FL
。我建议保持此功能的名称简短,最多2个字符,因为它会被多次使用。
而且,(⊂⍺)
函数如何工作?实际上,它将结果链接在一起,而不是函数本身。它只是enclose在数组(,⍵
)左边的结果,然后con catenate结果到它的右边(⊂
)。这导致将左结果“前置”到右侧的结果数组,但将其保持在一起,即不将其各个元素分开。第一次在这样的“链”中使用时需要FL
的原因是因为FL
无法确定右侧的数组是右侧函数的结果还是结果数组的结果,因此,通过第一次封闭,您确保FL
的正确参数始终是一个结果数组,而不是通过在其前面添加元素来破坏的结果。
值得注意的是,您也可以通过二元方式调用这样的链,在这种情况下,所有函数(不是X(f FL g FL∘⊂h)Y
)都将使用相同的两个参数进行二元调用。例如,(X f Y)(X g Y)(X h Y)
与M ← {⍺⍺ ⍵}
相同。但是,您可能希望单独调用某些函数。虽然与手头的问题没有直接关系,但这个monadic运算符会使函数忽略它们的左参数(如果有的话),并且对于这个目的非常有用,只是因为你避免使用括号:
f
所以,我们假设我们有四个函数g
,h
,p
和g
,我们想要调用p
和{{1}单词,同时保留f
和h
的左参数。现在我们已经实施了M
,我们可以这样做,X
是左参数,Y
是正确的:
X(f FL g M FL h FL∘⊂p M)Y
同样,我建议,如果你决定实现这个monadic运算符,你应该保持它的名字长达1个字符。
答案 1 :(得分:3)
创建一个近似Dyalog APL中的函数数组的结构的另一种方法是创建一个包含这些函数的命名空间数组。例如:
nss←⎕NS¨'' '' ''
nss.⍎ 'f←{⍵×2}' 'f←{⍵×4}' 'f←{2+⍵×3}'
nss.f 11
22 44 35
nss[2].f 2
8
答案 2 :(得分:1)
dfns工作区(与Dyalog APL一起提供)讨论了Function Arrays,并提供了多种处理方法。
或者,您可以使用以下monadic运算符作为操作数采用单行函数定义和/或名称的数组(命名函数可能是多行)并返回一个函数数组,然后可以应用该函数: / p>
r←{x}(fns Fns)y;nss;ns
nss←{⎕NS ⍬}¨fns
ns←'.(',⍨⍕⎕THIS
nss.⍎'f←'∘,¨ns∘,¨fns,¨')'
:If 900⌶⍬
x←⊢
:EndIf
r←x nss.f y