Cloud tech Cloud tech - 1 month ago 5
Scala Question

scalaz.concurrent.Task repeatEval only evaluate and Task.async once

I am learning scalaz stream at the moment, I am confused why repeatEval only evaluate Task.async once.

val result = Process
.repeatEval(Task.async[Unit](t => {
val result ="http://someUrl").mkString
})) //only print once

However, if I change Task.async to Task.delay. It evaluates the function infinitely. I dont know why is that

val result = Process
val result ="http://someUrl").mkString
})) //print infinitely

Many thanks in advance


As I mention in my answer to your recent question about Task, Task.async takes a function that registers callbacks—not some code that should be executed asynchronously. In the case of the other question, you actually want Task.async, since you're interoperating with a callback-based API.

Here it seems like you probably want Task.apply, not Task.delay. The two look similar, but delay simply suspends the computation—it doesn't use an ExecutorService to run it in a separate thread. You can see this in the following example:

import scalaz._, Scalaz._, concurrent._

val delayTask = Task.delay(Thread.sleep(5000))
val applyTask = Task(Thread.sleep(5000))

Nondeterminism[Task].both(delayTask, delayTask).run
Nondeterminism[Task].both(applyTask, applyTask).run

The delayTask version will take longer.