Is there any more functional alternative in Scala for an infinite loop?
while(true) {
if (condition) {
// Do something
} else {
Thread.sleep(interval);
}
}
You can do it recursively
@tailrec
def loop(): Nothing = {
if (condition) {
// Do something
} else {
Thread.sleep(interval);
}
loop()
}
One thing that you can do is using higher-order functions like Stream.continually
and pair it up with a for
comprehension:
import scala.util.Random
import scala.collection.immutable.Stream.continually
def rollTheDice: Int = Random.nextInt(6) + 1
for (n <- continually(rollTheDice)) {
println(s"the dice rolled $n")
}
This example itself is not purely functional due to the non-referentially transparent nextInt
method, but it's a possible construct that may help you think about function composition rather then using side effects.
As correctly point out in a recent comment, "[a]s of 2.13, Stream is deprecated. But the same method does exist in LazyList(import scala.collection.immutable.LazyList.continually)".
The following will work from 2.13 onward:
import scala.util.Random
import scala.collection.immutable.LazyList.continually
def rollTheDice: Int = Random.nextInt(6) + 1
for (n <- continually(rollTheDice)) {
println(s"the dice rolled $n")
}
You can see it in action and play around with it here on Scastie .
I guess infinite tail recursion:
@tailrec
def loop(): Nothing = {
if (condition) {
// Do something
} else {
Thread.sleep(interval);
}
loop()
}
Just to add to Stefano's great answer, in case someone is looking to a use-case like mine:
I was working on tasks from Kafka Streams course and needed to create an infinite stream of mock events to Kafka with some fields being completely random(amounts), but others rotated within a specific list(names).
The same approach with continually
can be used passing a method(via ETA expansion) to it and traversing the bounded variable afterwards:
for {record <- continually(newRandomTransaction _)
name <- List("John", "Stephane", "Alice")} {
producer.send(record(name))
}
where the signature of newRandomTransaction
is as follows:
def newRandomTransaction(name: String): ProducerRecord[String, String] = {
...
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.