了解APL中的DOMAIN ERROR:复制/粘贴结果分两步工作

时间:2015-12-02 21:29:55

标签: apl

我已经尝试过APL,但遇到了一个我无法理解的DOMAIN ERROR。

以下是我在gnu-apl中尝试的内容:


      isPrime ← {2=⍴(0=(⍳⍵)|⍵)/⍳⍵}
      (isPrime¨ ⍳20) / ⍳20
 DOMAIN ERROR
      (isPrime¨⍳20)/⍳20
      ^             ^

令我惊讶的是,当我刚刚评估了对isPrime的调用,并复制了生成的数组时,DOMAIN ERROR就消失了:


      (isPrime¨ ⍳20)
0 1 1 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0


      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

...但是将它分配给变量也不起作用:


      ps ← (isPrime¨ ⍳20)
      ps / ⍳20
DOMAIN ERROR
      ps/⍳20
      ^  ^

现在我很困惑。我原本以为这三种方式应该完全相同:

  1. 直接调用该函数
  2. 调用它并复制/粘贴其结果
  3. 使用临时变量而不是复制/粘贴。
  4. 我还使用基于浏览器的ngn/apl interpreter进行了双重检查。我不得不稍微更改代码,因为itoa从0开始计数。但是,DOMAIN ERROR是相同的:

    
    isPrime ← {2=⍴(0=(1+⍳⍵)|⍵)/(1+⍳⍵)}

    ⍝ (isPrime¨ (1+⍳20)) / (1+⍳20) ⍝ DOMAIN ERROR

    isPrime¨ (1+⍳20) ⍝ 0 1 1 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0

    ps ← isPrime¨ (1+⍳20) ⍝ ps / (1+⍳20) ⍝ DOMAIN ERROR

    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

    由于两个不同的实现显示相同的行为,我很确定错误是在我身边。不幸的是,我对APL的理解非常有限。

2 个答案:

答案 0 :(得分:2)

问题在于,从isPrime返回的每个元素本身都是一个单元素向量 - 并且还原需要一个布尔的simlpe向量。

⍴¨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。一元是“enlist”,它会将嵌套向量转换为简单的向量...)

为避免此问题,您应确保函数的结果是标量。虽然它看起来像这样,你将一个标量(2)与一个单元素矢量(⍴)进行比较,后者又使它成为一个矢量。因此,如果将one-elem向量转换为标量,则函数按预期工作:

isPrime ← {2=⍬⍴⍴(0=(1+⍳⍵)|⍵)/(1+⍳⍵)}

答案 1 :(得分:0)

我没有执行过您的代码,但我怀疑isPrime返回的每个元素本身都是一个向量。