在Perl 6中,我一直缺少的一个功能是像Haskell一样的intersperse
函数:Data.List.intersperse。
intersperse
函数接受一个元素和一个列表,并在列表元素之间“插入”该元素。
例如:
intersperse <X Y>, (<a b>, <c d>, <e f>);
应该返回这个序列:
<a b>, <X Y>, <c d>, <X Y>, <e f>
所以我一直在尝试将其作为自定义函数实现。
为了最大限度地提高可重用性,它应该具备以下特点:
- 支持任何类型的对象(包括列表和Nil)作为元素。
- 不以任何方式改变元素的容器化。
- 不会扁平化或以任何其他方式影响元素的内部结构。
- 如果输入列表作为懒惰序列给出,则返回一个懒惰序列,使其可以用于无限序列,例如
intersperse 42, 1..Inf
。
到目前为止,我想到了这个:
sub intersperse (\element, +list) {
((element xx *) Z list).map(|*)[1..*]
}
那就是:无限重复要插入的元素,将其与列表压缩,然后使用
map
对每个元组进行slip
,以去除由zip添加的嵌套层,而不会使原始元素扁平化,然后使用数组下标来删除插入元素的前导重复部分。它满足1-3的要求,但不满足4,因为数组下标操作急切地(即完全迭代输入序列,然后返回非惰性列表),从而在给定无限序列时导致此函数挂起。
有什么好方法可以实现此函数,以便满足所有4个要求?
join
的List
版本。 - Christopher Bottoms