8

Define a junction my $j = 1 | 2 | 3 | 4 | 5, now I want to get an array of its value [1 2 3 4 5], how should I implement this?

I tried $j.values but Perl6 gave me the whole junction as an element: [any((1), (2), (3), (4), (5))].

4

2 回答 2

9

据我所知,这是故意的。

想象一下 $j 包含一个哈希的连接:那么 $j.values 将是 Seq 的连接,而不是哈希本身。

如果你想要一个联结的数组,那么也许你应该从一个数组开始,并从中构建一个联结:

my @a = 1,2,3,4,5;
my $j = any(@a);

如果你真的想采用 Junction -> Array 的方式,你可以,但它会涉及使用 nqp,这是我在用户代码中不推荐的。

于 2017-04-23T08:07:27.097 回答
6

正如 Håkon Hægland 已经指出的那样,这不是您应该做的事情:

联结旨在用作布尔上下文中的匹配器;不支持结点的自省。如果您有自省的冲动,请改用 Set 或相关类型。

 -- docs.perl6.org/type/Junction

但是,这是可能的。

首先,您可以使用自动线程(即,在传递给需要类型参数的函数时自动评估联结的每个分支Any):

sub unjunc(Junction $j) {
    gather -> Any $_ { .take }.($j);
}

其次,您可以深入了解并手动提取值:

sub unjunc(Junction $j) {
    multi extract(Any $_) { .take }
    multi extract(Junction $_) {
        use nqp;
        my $list := nqp::getattr($_, Junction, '$!storage');
        my int $elems = nqp::elems($list);
        loop (my int $i = 0; $i < $elems; $i = $i + 1) {
            extract nqp::atpos($list, $i);
        }
    }
    gather extract $j;
}

如果您的联结是非递归的(即不包含您想要展平的其他联结),则可以简化后一种方法:

my $j := 1|2|3;
say nqp::p6bindattrinvres(nqp::create(List), List, '$!reified',
    nqp::getattr($j, Junction, '$!storage'));
于 2017-04-23T08:05:45.930 回答