首页 > 解决方案 > 如何从 perl6 中的匿名递归子返回?

问题描述

这符合我的预期。fib(13) 返回 233。

sub fib(Int $a --> Int) {
    return 0 if $a == 0;
    return 1 if $a == 1;

    return fib($a -1) + fib($a -2);
}

my $square = -> $x { $x * 2 };   # this works with no return value
my @list = <1 2 3 4 5 6 7 8 9>.map( $square );
# returns [2 4 6 8 10 12 14 16 18]

我尝试使用匿名子实现 fib()

my $fib = -> Int $x --> Int {
    return 0 if $x == 0;
    return 1 if $x == 1;
    return $fib($x - 1) + $fib($x - 2); 
}

$fib(13) 

使用显式返回运行时出现以下错误。

尝试在 test.p6 第 39 行的任何程序块之外返回

所以我摆脱了返回值。

my $fib = -> Int $x --> Int {
    0 if $x == 0;
    1 if $x == 1;
    $fib($x - 1) + $fib($x - 2); 
}

say $fib(13);

最后一个版本永远不会返回。有没有办法编写一个没有返回值的匿名递归函数?

标签: raku

解决方案


根据文档

不属于 Routine 类型的块(它是 Block 的子类)对于返回是透明的。

sub f() {
say <a b c>.map: { return 42 };
               #   ^^^^^^   exits &f, not just the block  }

最后一条语句是块的隐式返回值

所以你可以试试:

my $fib = -> Int $x --> Int {
    if ( $x == 0 ) {
        0;  # <-- Implicit return value
    }
    elsif ( $x == 1 ) {
        1;  # <-- Implicit return value
    }
    else {
        $fib($x - 1) + $fib($x - 2);  # <-- Implicit return value
    }
}

推荐阅读