# Repeating loop within a for comprehension

Is there an easy way to create a finite cycle within a for comprehension?

``````for{
x <- xs
y =???
z <- zs
}
``````

I’d like `y` to iterate through for example 1, 2, 3, 1, 2, 3… Another example is that a variable alternates `true`/`false`. I cannot use `y <- some_iterator` because that would make a concentric y-loop.
I encounter a requirement like this from time to time, and I usually convert it to a `foldLeft`, losing readability.

I’m probably motivated by a feature in Common Lisp `loop` which would translate to the Scala `for` comprehension something like the following. The `then` (meaning thereafter) part is evaluated each time (after the first) through the loop with the variable `y` bound to its value in the previous iteration.

``````for{
x <- xs
y = 1 then ((y + 1) % 2)
z <- zs
}
``````

alternatively

``````for{
x <- xs
y = true then !y
z <- zs
}
``````

There is no primitive that does quite that – I would zip on the previous generator.

``````val ys = Iterator.unfold(1)(y => Some(y, ((y + 1) % 2))

for {
(x, y) <- xs.zip(ys)
z <- zs
}

val ys = true #:: false #:: ys

for {
(x, y) <- xs.zip(ys)
z <- zs
}``````

What’s `Iterator.unfold`?

It’s like a “reverse fold”: you take a starting value, and a function that takes this value to generate an element and the next function input (as a tuple wrapped in an Option).

In this example, you start with `1`, and the function returns `Some((1,0))`. The first value of that tuple is the element returned by the iterator, the second is the value passed to the function for the next element. So by passing `0` to the function, we then get `Some((0, 1))`. This results in an infinite Iterator, returning alternating zeros and ones.

To create a finite iterator, the function would return a `None` to end it.

Okay, but where does it come from? I don’t see it in the `Iterator` companion object.

That’s because you don’t live in the Glorious Future yet.

https://scala-lang.org/files/archive/api/2.13.x/scala/collection/Iterator\$.html#unfoldA,S(f:S=%3EOption[(A,S)]):Iterator[A]

I’ve added this to the Scala Contributors forum, in case anyone would like to follow there and give your thumbs up.