How to write `intersperse` function in Perl 6

One thing I was missing in Perl 6 was the intersperse function like Haskell had :

The interpolation function takes an element, and the list β€œrearranges” this element between the elements of the list.

eg. this:

 intersperse <X Y>, (<a b>, <c d>, <e f>); 

... should return this sequence:

 <a b>, <X Y>, <c d>, <X Y>, <e f> 

So, I myself tried to implement it as a user-defined function. For maximum reuse, it should:

  • Support for any objects (including List and Nil) as elements.
  • Do not change the containerization of elements in any way.
  • Do not smooth or in any way affect the internal structure of the elements.
  • Returns a lazy sequence if the input list is given as a lazy sequence, so that it can be used in infinite sequences, as in intersperse 42, 1..Inf .

What I have come up with so far is this:

 sub intersperse (\element, +list) { ((element xx *) Z list).map(|*)[1..*] } 

That is: endlessly repeat the element that you want to insert, write it to the list, and then use map to slip each tuple to remove the nesting layer added by zip without aligning the original elements, and then use the array index to remove the leading repetition of the interspersed element.

It satisfies requirements 1-3, but not 4, because the index of the array works impatiently (i.e., iterates through the input sequence completely and then returns a non-face list) and, thus, causes this function to hang at a given infinite sequence.

What would be a good way to implement this feature so that it satisfies all 4 requirements?

+6
source share
1 answer

I am not very happy with the solutions I came up with, but here they go:

 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; } } } 

Perhaps this will inspire someone else to come up with something better ...

+9
source

All Articles