我在Perl 6中遗漏的一件事是intersperse
函数like Haskell has:
intersperse函数接受一个元素和一个列表,并在列表元素之间“穿插”该元素。
E.g。这样:
intersperse <X Y>, (<a b>, <c d>, <e f>);
...应该返回这个序列:
<a b>, <X Y>, <c d>, <X Y>, <e f>
所以我一直在尝试将它作为自定义函数实现。 为了最大限度地重复使用,它应该:
intersperse 42, 1..Inf
。到目前为止,我想出的是:
sub intersperse (\element, +list) {
((element xx *) Z list).map(|*)[1..*]
}
即:无限重复要穿插的元素,将其与列表一起压缩,然后使用map
来slip
每个元组,以便删除由zip添加的嵌套层,而不会展平原始元素,然后使用数组下标去除散布元素的前导重复。
它满足要求1-3,但不满足4,因为数组下标急切地操作(即完全迭代输入序列,然后返回非惰性列表),从而导致此函数当给出无限序列时挂起。
实现此功能以满足所有4项要求的好方法是什么?
答案 0 :(得分:10)
我对我提出的解决方案并不是特别满意,但是他们走了:
sub intersperse (\element, +list) {
map { ((element xx *) Z list).map(|*)[$_] },
1..(list.is-lazy ?? Inf !! list.elems * 2 - 1);
}
sub intersperse (\element, +list) {
gather for list {
FIRST .take, next;
take slip element, $_;
}
}
sub intersperse (\element, +list) {
list.map({ slip element, $_ }) does role {
method iterator {
my \it = callsame;
it.pull-one;
it;
}
}
}
也许它会为其他人提供更好的东西......