Raku 中的多子程序递归

anq*_*egi 17 raku

我正在学习乐乐,按照乐乐思考这本书

有一个练习,我需要定义阿克曼函数。

我定义了一个正整数子集:

subset Positive-Integer of Int where { $_ > 0}
Run Code Online (Sandbox Code Playgroud)

然后我使用以下方法遍历递归版本:

multi ackermann(0, Positive-Integer $n) {
    $n + 1;
}

multi ackermann(Positive-Integer $m, 0) {
    ackermann $m - 1, 1;
}

multi ackermann(Positive-Integer $m, Positive-Integer $n) {
    ackermann $m - 1, ackermann $m, $n - 1;
}
Run Code Online (Sandbox Code Playgroud)

但是执行我在执行时得到的代码:

阿克曼 3, 4;

> * * &ackermann
> > * * &ackermann
> > * * &ackermann
> > ackermann 3, 4
Cannot resolve caller ackermann(Int:D, Int:D); none of these signatures match:
    (0, Int $n)
    (Int $m, 0)
  in sub ackermann at <unknown file> line 3
  in sub ackermann at <unknown file> line 3
  in sub ackermann at <unknown file> line 3
  in sub ackermann at <unknown file> line 3
  in sub ackermann at <unknown file> line 3
  in sub ackermann at <unknown file> line 3
  in sub ackermann at <unknown file> line 3
  in block <unit> at <unknown file> line 2

> 
Run Code Online (Sandbox Code Playgroud)

我不明白这里发生了什么。

Eli*_*sen 14

从您的错误输出来看,您似乎正在尝试在 REPL 中运行这些示例。查看错误输出中的实际错误,似乎缺少这个候选:

multi ackermann(Positive-Integer $m, Positive-Integer $n) {
    ackermann $m - 1, ackermann $m, $n - 1;
}
Run Code Online (Sandbox Code Playgroud)

如果我将您示例的整个代码放入一个文件中:

subset Positive-Integer of Int where { $_ > 0}

multi ackermann(0, Positive-Integer $n) {
    $n + 1;
}

multi ackermann(Positive-Integer $m, 0) {
    ackermann $m - 1, 1;
}

multi ackermann(Positive-Integer $m, Positive-Integer $n) {
    ackermann $m - 1, ackermann $m, $n - 1;
}

say ackermann 3, 4;
Run Code Online (Sandbox Code Playgroud)

我得到了预期的结果 ( 125)。

因此,在我看来,您在将代码输入 REPL 会话时犯了某种错误。

专业提示:如果您尝试使用多行代码的示例,通常将每个示例存储到单独的文件中会更容易。这使您可以更好地监督代码,更容易进行更改并查看其结果,并且如果您想重新访问过去完成的示例,您可以稍后返回。

  • 感谢您的建议,我在 emacs 中使用 raku-mode 并将其发送到 raku-repl,❯ raku ackermann.raku 125 所以我终于在将其发送到 emacs 内的 raku-repl 的过程中找到了错误。 (2认同)