了解 APL 中的域错误:copy/pasting 分两步进行
Understanding DOMAIN ERROR in APL: copy/pasting results in two steps works
我已经尝试使用 APL,但 运行 进入域错误,我无法理解。
这是我在 gnu-apl 中尝试过的:
isPrime ← {2=⍴(0=(⍳⍵)|⍵)/⍳⍵}
(isPrime¨ ⍳20) / ⍳20
DOMAIN ERROR
(isPrime¨⍳20)/⍳20
^ ^
</pre>
令我惊讶的是,当我刚刚评估对 isPrime 的调用并复制结果数组时,DOMAIN ERROR 消失了:
(isPrime¨ ⍳20)<br>
0 1 1 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0
</pre>
0 1 1 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 / ⍳20
2 3 5 7 11 13 17 19
</pre>
... 但是将其分配给变量也不起作用:
ps ← (isPrime¨ ⍳20)
ps / ⍳20
DOMAIN ERROR
ps/⍳20
^ ^
</pre>
现在我很困惑。我原以为所有三种方式都应该以相同的方式工作:
- 直接调用函数
- 调用它并copy/pasting它的结果
- 使用临时变量代替 copy/paste。
我还仔细检查了基于浏览器的 ngn/apl interpreter。我不得不稍微更改代码,因为 itoa 从 0 开始计数。但是,域错误是相同的:
isPrime ← {2=⍴(0=(1+⍳⍵)|⍵)/(1+⍳⍵)}</p>
<p>⍝ (isPrime¨ (1+⍳20)) / (1+⍳20)
⍝ DOMAIN ERROR</p>
<p>isPrime¨ (1+⍳20)
⍝ 0 1 1 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0</p>
<p>ps ← isPrime¨ (1+⍳20)
⍝ ps / (1+⍳20)
⍝ DOMAIN ERROR</p>
<p>0 1 1 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 / (1+⍳20)
⍝ 2 3 5 7 11 13 17 19
</pre>
由于两个不同的实现表现出相同的行为,我很确定错误在我这边。不幸的是,我对APL的了解非常有限。
我没有执行你的代码,但我怀疑 isPrime return 中的每个元素本身就是一个向量。
问题是来自 isPrime 的 return 中的每个元素本身都是一个单元素向量 - 并且归约需要一个简单的布尔向量。
⍴¨isPrime¨⍳20
┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
│1│1│1│1│1│1│1│1│1│1│1│1│1│1│1│1│1│1│1│1│
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
(∊isPrime¨⍳20)/⍳20
2 3 5 7 11 13 17 19
(我不确定这是否适用于 GNU APL。monadic ∊
是 "enlist" 它将把嵌套向量转换成一个简单的向量...)
为避免此问题,您应确保函数的结果是标量。虽然它看起来像那样,但您将标量 (2
) 与 1 元素向量 (⍴) 进行比较,后者又使其成为向量。因此,如果您将该单元素向量转换为标量,您的函数将按预期工作:
isPrime ← {2=⍬⍴⍴(0=(1+⍳⍵)|⍵)/(1+⍳⍵)}
我已经尝试使用 APL,但 运行 进入域错误,我无法理解。
这是我在 gnu-apl 中尝试过的:
isPrime ← {2=⍴(0=(⍳⍵)|⍵)/⍳⍵} (isPrime¨ ⍳20) / ⍳20 DOMAIN ERROR (isPrime¨⍳20)/⍳20 ^ ^ </pre>
令我惊讶的是,当我刚刚评估对 isPrime 的调用并复制结果数组时,DOMAIN ERROR 消失了:
(isPrime¨ ⍳20)<br> 0 1 1 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 </pre>
0 1 1 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 / ⍳20 2 3 5 7 11 13 17 19 </pre>
... 但是将其分配给变量也不起作用:
ps ← (isPrime¨ ⍳20) ps / ⍳20 DOMAIN ERROR ps/⍳20 ^ ^ </pre>
现在我很困惑。我原以为所有三种方式都应该以相同的方式工作:
- 直接调用函数
- 调用它并copy/pasting它的结果
- 使用临时变量代替 copy/paste。
我还仔细检查了基于浏览器的 ngn/apl interpreter。我不得不稍微更改代码,因为 itoa 从 0 开始计数。但是,域错误是相同的:
isPrime ← {2=⍴(0=(1+⍳⍵)|⍵)/(1+⍳⍵)}</p> <p>⍝ (isPrime¨ (1+⍳20)) / (1+⍳20) ⍝ DOMAIN ERROR</p> <p>isPrime¨ (1+⍳20) ⍝ 0 1 1 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0</p> <p>ps ← isPrime¨ (1+⍳20) ⍝ ps / (1+⍳20) ⍝ DOMAIN ERROR</p> <p>0 1 1 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 / (1+⍳20) ⍝ 2 3 5 7 11 13 17 19 </pre>
由于两个不同的实现表现出相同的行为,我很确定错误在我这边。不幸的是,我对APL的了解非常有限。
我没有执行你的代码,但我怀疑 isPrime return 中的每个元素本身就是一个向量。
问题是来自 isPrime 的 return 中的每个元素本身都是一个单元素向量 - 并且归约需要一个简单的布尔向量。
⍴¨isPrime¨⍳20
┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
│1│1│1│1│1│1│1│1│1│1│1│1│1│1│1│1│1│1│1│1│
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
(∊isPrime¨⍳20)/⍳20
2 3 5 7 11 13 17 19
(我不确定这是否适用于 GNU APL。monadic ∊
是 "enlist" 它将把嵌套向量转换成一个简单的向量...)
为避免此问题,您应确保函数的结果是标量。虽然它看起来像那样,但您将标量 (2
) 与 1 元素向量 (⍴) 进行比较,后者又使其成为向量。因此,如果您将该单元素向量转换为标量,您的函数将按预期工作:
isPrime ← {2=⍬⍴⍴(0=(1+⍳⍵)|⍵)/(1+⍳⍵)}